• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

inventree / inventree-app / 12180381076

05 Dec 2024 01:08PM UTC coverage: 8.616% (-0.01%) from 8.63%
12180381076

push

github

web-flow
Barcode scanner updates (#562)

* Add BUILDING.md

* Replace scaning library

- Out with qr_code_scanner
- In with flutter_zxing

* Update specs for jdk / kotlin / gradle

- NFI what this all means?

* Refactor barcode scanning widget

* Refactor barcode overlay

* Add handlers

* Update release notes

* Fix AppBar color

* Enhance attachment widget

* remove unused import

* Improved icon

* Select theme from main drawer

0 of 100 new or added lines in 8 files covered. (0.0%)

1 existing line in 1 file now uncovered.

723 of 8391 relevant lines covered (8.62%)

0.3 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/lib/barcode/camera_controller.dart
1
import "dart:math";
2
import "package:flutter/material.dart";
3
import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
4
import "package:inventree/app_colors.dart";
5
import "package:inventree/preferences.dart";
6

7
import "package:flutter_zxing/flutter_zxing.dart";
8

9
import "package:inventree/l10.dart";
10

11
import "package:inventree/barcode/handler.dart";
12
import "package:inventree/barcode/controller.dart";
13

14
/*
15
 * Barcode controller which uses the device's camera to scan barcodes.
16
 * Under the hood it uses the qr_code_scanner package.
17
 */
18
class CameraBarcodeController extends InvenTreeBarcodeController {
19
  const CameraBarcodeController(BarcodeHandler handler, {Key? key})
×
20
      : super(handler, key: key);
×
21

22
  @override
×
23
  State<StatefulWidget> createState() => _CameraBarcodeControllerState();
×
24
}
25

26
class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
27
  _CameraBarcodeControllerState() : super();
×
28

29
  bool flash_status = false;
30

31
  int scan_delay = 500;
32
  bool single_scanning = false;
33
  bool scanning_paused = false;
34

35
  String scanned_code = "";
36

NEW
37
  @override
×
38
  void initState() {
NEW
39
    super.initState();
×
NEW
40
    _loadSettings();
×
41
  }
42

43
  /*
44
   * Load the barcode scanning settings
45
   */
46
  Future<void> _loadSettings() async {
×
47
    bool _single = await InvenTreeSettingsManager()
×
48
        .getBool(INV_BARCODE_SCAN_SINGLE, false);
×
49

NEW
50
    int _delay = await InvenTreeSettingsManager()
×
NEW
51
        .getValue(INV_BARCODE_SCAN_DELAY, 500) as int;
×
52

53
    if (mounted) {
×
54
      setState(() {
×
NEW
55
        scan_delay = _delay;
×
56
        single_scanning = _single;
×
57
        scanning_paused = false;
×
58
      });
59
    }
60
  }
61

UNCOV
62
  @override
×
63
  Future<void> pauseScan() async {
64
    if (mounted) {
×
NEW
65
      setState(() {
×
NEW
66
        scanning_paused = true;
×
67
      });
68
    }
69
  }
70

71
  @override
×
72
  Future<void> resumeScan() async {
NEW
73
    if (mounted) {
×
NEW
74
      setState(() {
×
NEW
75
        scanning_paused = false;
×
76
      });
77
    }
78
  }
79

80
  /*
81
   * Callback function when a barcode is scanned
82
   */
NEW
83
  void _onScanSuccess(Code? code) {
×
84

NEW
85
    if (scanning_paused) {
×
86
      return;
87
    }
88

NEW
89
    String barcode_data = code?.text ?? "";
×
90

91
    if (mounted) {
×
92
      setState(() {
×
NEW
93
        scanned_code = barcode_data;
×
NEW
94
        scanning_paused = barcode_data.isNotEmpty;
×
95
      });
96
    }
97

NEW
98
    if (barcode_data.isNotEmpty) {
×
NEW
99
      handleBarcodeData(barcode_data).then((_) {
×
NEW
100
        if (!single_scanning && mounted) {
×
101
          // Resume next scan
NEW
102
          setState(() {
×
NEW
103
            scanning_paused = false;
×
104
          });
105
        }
106
      });
107
    }
108

109
  }
110

111
  /*
112
   * Build the barcode scanner overlay
113
   */
NEW
114
  FixedScannerOverlay BarcodeOverlay(BuildContext context) {
×
115

116
    // Note: Copied from reader_widget.dart:ReaderWidget.build
NEW
117
    final Size size = MediaQuery.of(context).size;
×
NEW
118
    final double cropSize = min(size.width, size.height) * 0.5;
×
119

NEW
120
    return FixedScannerOverlay(
×
NEW
121
      borderColor: scanning_paused ? COLOR_WARNING : COLOR_ACTION,
×
122
      overlayColor: Colors.black45,
123
      borderRadius: 1,
124
      borderLength: 15,
125
      borderWidth: 8,
126
      cutOutSize: cropSize,
127
    );
128
  }
129

130
  /*
131
   * Build the barcode reader widget
132
   */
NEW
133
  Widget BarcodeReader(BuildContext context) {
×
134

NEW
135
    return ReaderWidget(
×
NEW
136
      onScan: _onScanSuccess,
×
137
      isMultiScan: false,
138
      tryHarder: true,
139
      tryInverted: true,
140
      tryRotate: true,
141
      showGallery: false,
NEW
142
      scanDelay: Duration(milliseconds: scan_delay),
×
143
      resolution: ResolutionPreset.high,
144
      lensDirection: CameraLensDirection.back,
145
      flashOnIcon: const Icon(Icons.flash_on),
146
      flashOffIcon: const Icon(Icons.flash_off),
147
      toggleCameraIcon: const Icon(TablerIcons.camera_rotate),
148
      actionButtonsBackgroundBorderRadius:
NEW
149
      BorderRadius.circular(40),
×
NEW
150
      scannerOverlay: BarcodeOverlay(context),
×
NEW
151
      actionButtonsBackgroundColor: Colors.black.withOpacity(0.7),
×
152
    );
153
  }
154

NEW
155
  Widget topCenterOverlay() {
×
NEW
156
    return SafeArea(
×
NEW
157
      child: Align(
×
158
        alignment: Alignment.topCenter,
NEW
159
        child: Padding(
×
NEW
160
          padding: EdgeInsets.all(10),
×
NEW
161
          child: Text(
×
NEW
162
            widget.handler.getOverlayText(context),
×
NEW
163
            style: TextStyle(
×
164
              color: Colors.white,
165
              fontSize: 16,
166
              fontWeight: FontWeight.bold
167
            )
168
          )
169
        )
170
      )
171
    );
172
  }
173

NEW
174
  Widget bottomCenterOverlay() {
×
175

176
    String info_text = scanning_paused ? L10().barcodeScanPaused : L10().barcodeScanPause;
×
177

NEW
178
    return SafeArea(
×
NEW
179
      child: Align(
×
180
        alignment: Alignment.bottomCenter,
NEW
181
        child: Padding(
×
NEW
182
          padding: EdgeInsets.all(10),
×
NEW
183
          child: Text(
×
NEW
184
              scanned_code.isNotEmpty ? scanned_code : info_text,
×
185
              textAlign: TextAlign.center,
NEW
186
              style: TextStyle(
×
187
                color: Colors.white,
188
                fontSize: 16,
189
                fontWeight: FontWeight.bold
190
              )
191
          ),
192
        )
193
      )
194
    );
195
  }
196

197

198
  /*
199
   *  Display an overlay at the bottom right of the screen
200
   */
NEW
201
  Widget bottomRightOverlay() {
×
NEW
202
    return SafeArea(
×
NEW
203
        child: Align(
×
204
            alignment: Alignment.bottomRight,
NEW
205
            child: Padding(
×
NEW
206
                padding: EdgeInsets.all(10),
×
NEW
207
                child: ClipRRect(
×
NEW
208
                    borderRadius: BorderRadius.circular(40),
×
NEW
209
                    child: ColoredBox(
×
210
                        color: Colors.black45,
NEW
211
                        child: Row(
×
212
                            mainAxisSize: MainAxisSize.min,
NEW
213
                            children: scanning_paused ? [] : [
×
NEW
214
                              CircularProgressIndicator(
×
215
                                  value: null
216
                              )
217
                              // actionIcon,
218
                            ]
219
                        )
220
                    )
221
                )
222
            )
223
        )
224
    );
225
  }
226

NEW
227
  @override
×
228
  Widget build(BuildContext context) {
229

NEW
230
    return Scaffold(
×
NEW
231
      appBar: AppBar(
×
NEW
232
        backgroundColor: COLOR_APP_BAR,
×
NEW
233
        title: Text(L10().scanBarcode),
×
234
      ),
NEW
235
      body: GestureDetector(
×
NEW
236
        onTap: () async {
×
NEW
237
          setState(() {
×
NEW
238
            scanning_paused = !scanning_paused;
×
239
          });
240
        },
NEW
241
        child: Stack(
×
NEW
242
          children: <Widget>[
×
NEW
243
            Column(
×
NEW
244
              children: [
×
NEW
245
                Expanded(
×
NEW
246
                    child: BarcodeReader(context)
×
247
                ),
248
              ],
249
            ),
NEW
250
            topCenterOverlay(),
×
NEW
251
            bottomCenterOverlay(),
×
NEW
252
            bottomRightOverlay(),
×
253
          ],
254
        ),
255
      ),
256
    );
257
  }
258

259
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc