-
-
Notifications
You must be signed in to change notification settings - Fork 279
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
feature/#55 - SQLite local database, and refactoring with StatefulWidget's
- Loading branch information
Showing
21 changed files
with
1,347 additions
and
1,463 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 0 additions & 101 deletions
101
packages/smooth_app/lib/data_models/choose_page_model.dart
This file was deleted.
Oops, something went wrong.
198 changes: 75 additions & 123 deletions
198
packages/smooth_app/lib/data_models/continuous_scan_model.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,154 +1,106 @@ | ||
import 'package:carousel_slider/carousel_controller.dart'; | ||
import 'package:flutter/foundation.dart'; | ||
import 'package:flutter/widgets.dart'; | ||
import 'package:openfoodfacts/model/Product.dart'; | ||
import 'package:qr_code_scanner/qr_code_scanner.dart'; | ||
import 'package:smooth_app/cards/product_cards/smooth_product_card_edit.dart'; | ||
import 'package:smooth_app/cards/product_cards/smooth_product_card_found.dart'; | ||
import 'package:smooth_app/cards/product_cards/smooth_product_card_not_found.dart'; | ||
import 'package:smooth_app/cards/product_cards/smooth_product_card_loading.dart'; | ||
import 'package:smooth_app/cards/product_cards/smooth_product_card_thanks.dart'; | ||
import 'package:smooth_app/database/full_products_database.dart'; | ||
|
||
enum ScannedProductState { FOUND, NOT_FOUND, LOADING } | ||
|
||
class ContinuousScanModel extends ChangeNotifier { | ||
ContinuousScanModel({@required this.contributionMode}) { | ||
carouselController = CarouselController(); | ||
import 'package:smooth_app/database/barcode_product_query.dart'; | ||
import 'package:smooth_app/database/local_database.dart'; | ||
|
||
enum ScannedProductState { | ||
FOUND, | ||
NOT_FOUND, | ||
LOADING, | ||
THANKS, | ||
} | ||
|
||
scannedBarcodes = <String, ScannedProductState>{}; | ||
cardTemplates = <String, Widget>{}; | ||
class ContinuousScanModel { | ||
ContinuousScanModel({@required bool contributionMode}) | ||
: _contributionMode = contributionMode; | ||
|
||
final Map<String, ScannedProductState> _states = | ||
<String, ScannedProductState>{}; | ||
final Map<String, Product> _products = <String, Product>{}; | ||
final List<String> _barcodes = <String>[]; | ||
bool _contributionMode; | ||
QRViewController _scannerController; | ||
String _barcodeTrustCheck; | ||
LocalDatabase _localDatabase; | ||
|
||
bool get isNotEmpty => getBarcodes().isNotEmpty; | ||
bool get contributionMode => _contributionMode; | ||
|
||
List<String> getBarcodes() => _barcodes; | ||
|
||
void setBarcodeState( | ||
final String barcode, | ||
final ScannedProductState state, | ||
) { | ||
_states[barcode] = state; | ||
_localDatabase.dummyNotifyListeners(); | ||
} | ||
|
||
final GlobalKey scannerViewKey = GlobalKey(debugLabel: 'Barcode Scanner'); | ||
QRViewController scannerController; | ||
CarouselController carouselController; | ||
|
||
Map<String, ScannedProductState> scannedBarcodes; | ||
Map<String, Widget> cardTemplates; | ||
|
||
List<Product> foundProducts = <Product>[]; | ||
|
||
String barcodeTrustCheck; | ||
ScannedProductState getBarcodeState(final String barcode) => _states[barcode]; | ||
|
||
bool contributionMode = false; | ||
Product getProduct(final String barcode) => _products[barcode]; | ||
|
||
bool firstScan = true; | ||
void setLocalDatabase(final LocalDatabase localDatabase) => | ||
_localDatabase = localDatabase; | ||
|
||
void setupScanner(QRViewController controller) { | ||
scannerController = controller; | ||
scannerController.scannedDataStream.listen((String barcode) { | ||
onScan(barcode); | ||
}); | ||
_scannerController = controller; | ||
_scannerController.scannedDataStream.listen( | ||
(String barcode) => onScan(barcode), | ||
); | ||
} | ||
|
||
void onScan(String code) { | ||
print('Barcode detected : $code'); | ||
if (barcodeTrustCheck != code) { | ||
barcodeTrustCheck = code; | ||
return; | ||
} | ||
if (addBarcode(code)) { | ||
_generateScannedProductsCardTemplates(); | ||
if (!firstScan) { | ||
carouselController.animateToPage( | ||
cardTemplates.length - 1, | ||
); | ||
} else { | ||
firstScan = false; | ||
List<Product> getFoundProducts() { | ||
final List<Product> result = <Product>[]; | ||
for (final String barcode in _barcodes) { | ||
if (getBarcodeState(barcode) == ScannedProductState.FOUND) { | ||
result.add(_products[barcode]); | ||
} | ||
} | ||
return result; | ||
} | ||
|
||
void onScanAlt(String code, List<Offset> offsets) { | ||
Future<void> onScan(String code) async { | ||
print('Barcode detected : $code'); | ||
if (addBarcode(code)) { | ||
_generateScannedProductsCardTemplates(); | ||
if (cardTemplates.isNotEmpty) { | ||
carouselController.animateToPage( | ||
cardTemplates.length - 1, | ||
); | ||
} | ||
if (_barcodeTrustCheck != code) { | ||
_barcodeTrustCheck = code; | ||
return; | ||
} | ||
_addBarcode(code); | ||
} | ||
|
||
Future<bool> _generateScannedProductsCardTemplates( | ||
{bool switchMode = false}) async { | ||
final FullProductsDatabase productsDatabase = FullProductsDatabase(); | ||
|
||
for (final String scannedBarcode in scannedBarcodes.keys) { | ||
switch (scannedBarcodes[scannedBarcode]) { | ||
case ScannedProductState.FOUND: | ||
if (switchMode) { | ||
final Product product = await productsDatabase.getProduct( | ||
scannedBarcode); // Acceptable thanks to offline first | ||
setCardTemplate( | ||
scannedBarcode, | ||
contributionMode | ||
? SmoothProductCardEdit( | ||
heroTag: product.barcode, product: product) | ||
: SmoothProductCardFound( | ||
heroTag: product.barcode, product: product)); | ||
} | ||
break; | ||
case ScannedProductState.NOT_FOUND: | ||
break; | ||
case ScannedProductState.LOADING: | ||
final bool result = | ||
await productsDatabase.checkAndFetchProduct(scannedBarcode); | ||
if (result) { | ||
scannedBarcodes[scannedBarcode] = ScannedProductState.FOUND; | ||
final Product product = | ||
await productsDatabase.getProduct(scannedBarcode); | ||
setCardTemplate( | ||
scannedBarcode, | ||
contributionMode | ||
? SmoothProductCardEdit( | ||
heroTag: product.barcode, product: product) | ||
: SmoothProductCardFound( | ||
heroTag: product.barcode, product: product)); | ||
foundProducts.add(product); | ||
} else { | ||
scannedBarcodes[scannedBarcode] = ScannedProductState.NOT_FOUND; | ||
setCardTemplate( | ||
scannedBarcode, | ||
SmoothProductCardNotFound( | ||
barcode: scannedBarcode, | ||
callback: () { | ||
setCardTemplate(scannedBarcode, SmoothProductCardThanks()); | ||
}, | ||
), | ||
); | ||
} | ||
break; | ||
} | ||
Future<void> onScanAlt(String code, List<Offset> offsets) async { | ||
print('Barcode detected : $code'); | ||
_addBarcode(code); | ||
} | ||
|
||
void contributionModeSwitch(bool value) { | ||
if (_contributionMode != value) { | ||
_contributionMode = value; | ||
_localDatabase.dummyNotifyListeners(); | ||
} | ||
return true; | ||
} | ||
|
||
bool addBarcode(String newBarcode) { | ||
if (scannedBarcodes[newBarcode] == null) { | ||
scannedBarcodes[newBarcode] = ScannedProductState.LOADING; | ||
cardTemplates[newBarcode] = SmoothProductCardLoading(barcode: newBarcode); | ||
notifyListeners(); | ||
bool _addBarcode(final String barcode) { | ||
if (getBarcodeState(barcode) == null) { | ||
_barcodes.add(barcode); | ||
setBarcodeState(barcode, ScannedProductState.LOADING); | ||
_loadBarcode(barcode); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
void setProductState(String barcode, ScannedProductState state) { | ||
scannedBarcodes[barcode] = state; | ||
notifyListeners(); | ||
} | ||
|
||
void setCardTemplate(String barcode, Widget cardTemplate) { | ||
cardTemplates[barcode] = cardTemplate; | ||
notifyListeners(); | ||
} | ||
|
||
void contributionModeSwitch(bool value) { | ||
contributionMode = value; | ||
_generateScannedProductsCardTemplates(switchMode: true); | ||
notifyListeners(); | ||
Future<void> _loadBarcode(final String barcode) async { | ||
final Product product = await BarcodeProductQuery(barcode).getProduct(); | ||
if (product != null) { | ||
_localDatabase.putProduct(product); | ||
_products[barcode] = product; | ||
setBarcodeState(barcode, ScannedProductState.FOUND); | ||
} else { | ||
setBarcodeState(barcode, ScannedProductState.NOT_FOUND); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.