2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-07-01 11:20:41 +00:00

Use FVM in GitHub Actions and migrate to Flutter 3.32.4 (#641)

* feat: implement Flutter version management using FVM across CI workflows

* Flutter 3.29.3 + minor Package upgrades

* Replace deprecated `withOpacity`

* Upgrade major package versions without breaking changes.

* Disable unnecessary_async rule

Re-enable later

* New language version and automated fixes

- unnecessary_breaks
- unnecessary_underscore

* Update BUILDING.md to use fvm commands

* Add gitignore files for Android and iOS build artifacts

* Migrate iOS dependencies to Swift Package Manager

This is being done automatically by Flutter

* Flutter 3.32.4

* New sdk version

* docs: add IDE setup instructions and troubleshooting guide for FVM integration
This commit is contained in:
Ben Hagen
2025-06-23 11:42:05 +02:00
committed by GitHub
parent cf012b2531
commit c4e33a4c1a
27 changed files with 630 additions and 330 deletions

View File

@ -593,10 +593,8 @@ class InvenTreeAPI {
L10().serverAuthenticationError,
L10().invalidUsernamePassword,
);
break;
default:
showStatusCodeError(apiUrl, response.statusCode);
break;
}
debug("Token request failed: STATUS ${response.statusCode}");
@ -1342,7 +1340,6 @@ class InvenTreeAPI {
"responseData": response.data.toString(),
}
);
break;
}
} else {
@ -1414,7 +1411,6 @@ class InvenTreeAPI {
"endpoint": url,
}
);
break;
}
showServerError(

View File

@ -1171,7 +1171,6 @@ class _APIFormWidgetState extends State<APIFormWidget> {
case "related field":
case "choice":
widgets.add(Divider(height: 15));
break;
default:
break;
}
@ -1202,10 +1201,8 @@ class _APIFormWidgetState extends State<APIFormWidget> {
case "choice":
widgets.add(Divider(height: 15));
spacerRequired = false;
break;
default:
spacerRequired = true;
break;
}
}
@ -1344,7 +1341,6 @@ class _APIFormWidgetState extends State<APIFormWidget> {
}
}
break;
}
if (!match) {
@ -1473,43 +1469,36 @@ class _APIFormWidgetState extends State<APIFormWidget> {
extractNonFieldErrors(response);
checkInvalidErrors(response);
break;
case 401:
showSnackIcon(
"401: " + L10().response401,
success: false
);
break;
case 403:
showSnackIcon(
"403: " + L10().response403,
success: false,
);
break;
case 404:
showSnackIcon(
"404: " + L10().response404,
success: false,
);
break;
case 405:
showSnackIcon(
"405: " + L10().response405,
success: false,
);
break;
case 500:
showSnackIcon(
"500: " + L10().response500,
success: false,
);
break;
default:
showSnackIcon(
"${response.statusCode}: " + L10().responseInvalid,
success: false,
);
break;
}
setState(() {

View File

@ -88,7 +88,6 @@ Future<Object?> scanBarcode(BuildContext context, {BarcodeHandler? handler}) asy
switch (barcodeControllerType) {
case BARCODE_CONTROLLER_WEDGE:
controller = WedgeBarcodeController(handler);
break;
case BARCODE_CONTROLLER_CAMERA:
default:
// Already set as default option
@ -97,7 +96,7 @@ Future<Object?> scanBarcode(BuildContext context, {BarcodeHandler? handler}) asy
return Navigator.of(context).push(
PageRouteBuilder(
pageBuilder: (context, _, __) => controller,
pageBuilder: (context, _, _) => controller,
opaque: false,
)
);

View File

@ -24,7 +24,7 @@ import "package:inventree/barcode/controller.dart";
*/
class CameraBarcodeController extends InvenTreeBarcodeController {
const CameraBarcodeController(BarcodeHandler handler, {Key? key})
: super(handler, key: key);
: super(handler, key: key);
@override
State<StatefulWidget> createState() => _CameraBarcodeControllerState();
@ -43,7 +43,7 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
String scanned_code = "";
final MobileScannerController controller = MobileScannerController(
autoZoom: true
autoZoom: true,
);
@override
@ -63,11 +63,14 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
* Load the barcode scanning settings
*/
Future<void> _loadSettings() async {
bool _single = await InvenTreeSettingsManager()
.getBool(INV_BARCODE_SCAN_SINGLE, false);
bool _single = await InvenTreeSettingsManager().getBool(
INV_BARCODE_SCAN_SINGLE,
false,
);
int _delay = await InvenTreeSettingsManager()
.getValue(INV_BARCODE_SCAN_DELAY, 500) as int;
int _delay =
await InvenTreeSettingsManager().getValue(INV_BARCODE_SCAN_DELAY, 500)
as int;
if (mounted) {
setState(() {
@ -80,7 +83,6 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
@override
Future<void> pauseScan() async {
if (mounted) {
setState(() {
scanning_paused = true;
@ -90,7 +92,6 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
@override
Future<void> resumeScan() async {
controller.start();
if (mounted) {
@ -114,8 +115,7 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
setState(() {
multiple_barcodes = false;
});
}
else if (result.barcodes.length > 1) {
} else if (result.barcodes.length > 1) {
setState(() {
multiple_barcodes = true;
});
@ -177,7 +177,7 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
sentryReportError(
"CameraBarcodeController.onControllerCreated",
error,
null
null,
);
}
@ -185,7 +185,7 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
showSnackIcon(
L10().cameraCreationError,
icon: TablerIcons.camera_x,
success: false
success: false,
);
if (OneContext.hasContext) {
@ -195,7 +195,6 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
}
Widget BarcodeOverlay(BuildContext context) {
final Size screenSize = MediaQuery.of(context).size;
final double width = screenSize.width;
final double height = screenSize.height;
@ -220,14 +219,11 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
width: D,
height: D,
decoration: BoxDecoration(
border: Border.all(
color: overlayColor,
width: 4,
),
border: Border.all(color: overlayColor, width: 4),
),
)
)
]
),
),
],
);
}
@ -235,7 +231,6 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
* Build the barcode reader widget
*/
Widget BarcodeReader(BuildContext context) {
final Size screenSize = MediaQuery.of(context).size;
final double width = screenSize.width;
final double height = screenSize.height;
@ -250,7 +245,7 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
scanWindow: Rect.fromCenter(
center: Offset(width / 2, height / 2),
width: D,
height: D
height: D,
),
onDetect: (result) {
onScanSuccess(result);
@ -263,28 +258,23 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
child: Align(
alignment: Alignment.topCenter,
child: Padding(
padding: EdgeInsets.only(
left: 10,
right: 10,
top: 75,
bottom: 10
),
padding: EdgeInsets.only(left: 10, right: 10, top: 75, bottom: 10),
child: Text(
widget.handler.getOverlayText(context),
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold
)
)
)
)
fontWeight: FontWeight.bold,
),
),
),
),
);
}
Widget bottomCenterOverlay() {
String info_text = scanning_paused ? L10().barcodeScanPaused : L10().barcodeScanPause;
String info_text =
scanning_paused ? L10().barcodeScanPaused : L10().barcodeScanPause;
String text = scanned_code.isNotEmpty ? scanned_code : info_text;
@ -296,28 +286,22 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
child: Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.only(
left: 10,
right: 10,
top: 10,
bottom: 75
),
padding: EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 75),
child: Text(
text,
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold
)
text,
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
)
)
),
),
);
}
Widget? buildActions(BuildContext context) {
List<SpeedDialChild> actions = [
SpeedDialChild(
child: Icon(flash_status ? TablerIcons.bulb_off : TablerIcons.bulb),
@ -329,26 +313,22 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
flash_status = !flash_status;
});
}
}
},
),
SpeedDialChild(
child: Icon(TablerIcons.camera),
label: L10().switchCamera,
onTap: () async {
controller.switchCamera();
}
)
},
),
];
return SpeedDial(
icon: Icons.more_horiz,
children: actions,
);
return SpeedDial(icon: Icons.more_horiz, children: actions);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: COLOR_APP_BAR,
@ -366,19 +346,12 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
},
child: Stack(
children: <Widget>[
Column(
children: [
Expanded(
child: BarcodeReader(context)
),
],
),
Column(children: [Expanded(child: BarcodeReader(context))]),
topCenterOverlay(),
bottomCenterOverlay()
bottomCenterOverlay(),
],
),
),
);
}
}

View File

@ -584,7 +584,6 @@ class InvenTreeModel {
L10().itemDeleted,
success: false,
);
break;
default:
String detail = L10().errorFetch;
detail += "\n${L10().statusCode}: ${response.statusCode}";
@ -594,7 +593,6 @@ class InvenTreeModel {
L10().serverError,
detail
);
break;
}
return false;

View File

@ -66,15 +66,12 @@ Future<void> main() async {
switch (orientation) {
case SCREEN_ORIENTATION_PORTRAIT:
orientations.add(DeviceOrientation.portraitUp);
break;
case SCREEN_ORIENTATION_LANDSCAPE:
orientations.add(DeviceOrientation.landscapeLeft);
break;
default:
orientations.add(DeviceOrientation.portraitUp);
orientations.add(DeviceOrientation.landscapeLeft);
orientations.add(DeviceOrientation.landscapeRight);
break;
}
SystemChrome.setPreferredOrientations(orientations).then((_) {

View File

@ -143,14 +143,11 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
switch (screenOrientation) {
case SCREEN_ORIENTATION_PORTRAIT:
orientationIcon = Icons.screen_lock_portrait;
break;
case SCREEN_ORIENTATION_LANDSCAPE:
orientationIcon = Icons.screen_lock_landscape;
break;
case SCREEN_ORIENTATION_SYSTEM:
default:
orientationIcon = Icons.screen_rotation;
break;
}
return Scaffold(

View File

@ -104,11 +104,9 @@ class _InvenTreeBarcodeSettingsState extends State<InvenTreeBarcodeSettingsWidge
switch (barcodeScanType) {
case BARCODE_CONTROLLER_WEDGE:
barcodeInputIcon = Icon(Icons.barcode_reader);
break;
case BARCODE_CONTROLLER_CAMERA:
default:
barcodeInputIcon = Icon(TablerIcons.camera);
break;
}
return Scaffold(

View File

@ -163,7 +163,6 @@ Future<void> showErrorDialog(String title, {String description = "", APIResponse
)
);
}
break;
default:
// Unhandled server response
children.add(
@ -180,7 +179,6 @@ Future<void> showErrorDialog(String title, {String description = "", APIResponse
)
);
break;
}
}

View File

@ -68,7 +68,7 @@ class _PartSupplierState extends RefreshableState<PartSupplierWidget> {
return ListView.separated(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
separatorBuilder: (_, __) => const Divider(height: 3),
separatorBuilder: (_, _) => const Divider(height: 3),
itemCount: _supplierParts.length,
itemBuilder: _supplierPartTile,
);