Skip to content

Commit

Permalink
Merge pull request #30 from bloedboemmel/v1.0.6
Browse files Browse the repository at this point in the history
V1.0.6
  • Loading branch information
bloedboemmel committed May 16, 2023
2 parents c46afa9 + 96aa47c commit 2120c7d
Show file tree
Hide file tree
Showing 12 changed files with 266 additions and 113 deletions.
3 changes: 2 additions & 1 deletion distribution/whatsnew/whatsnew-de-DE
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Es wurde ein bisschen unter der Haube aufgeräumt. Jetzt wird bei Fehler auch fleißig mitgeloggt
Die ganze App ist nun auch für Menschen mit Sehschwäche einsetzbar.
Außerdem wurde ein bisschen unter der Haube aufgeräumt. Jetzt wird bei Fehler auch fleißig mitgeloggt

Happy Scanning!
2 changes: 2 additions & 0 deletions distribution/whatsnew/whatsnew-en-US
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
We added semantics for visually impaired people.

We improved some things and enabled Error Logging

Happy Scanning!
52 changes: 46 additions & 6 deletions lib/ProductView.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,15 @@ class _Product extends State<ProductView> {
}

// By default, show a loading spinner.
return const Center(child: CircularProgressIndicator());
return const Center(child: CircularProgressIndicator(semanticsLabel: "Loading",));
},
)
);
}
Widget productNotFound(BuildContext context){
return Stack(
return Semantics(
focused: true,
child: Stack(
children: [
Align(
child:
Expand Down Expand Up @@ -150,6 +152,7 @@ class _Product extends State<ProductView> {
),
)
]
)
);
}

Expand All @@ -171,7 +174,10 @@ class _Product extends State<ProductView> {

}
if (foodPrefs.isEmpty){
return Stack(
return Semantics(
label: ProductTextSemantics(product, suitable, foodPrefs),
focused: true,
child: Stack(
children: [
Align(
child:
Expand All @@ -184,10 +190,14 @@ class _Product extends State<ProductView> {
),
ProductText(product.title)
]
)
);
}
else if(foodPrefs.length == 1){
return Stack(
return Semantics(
label: ProductTextSemantics(product, suitable, foodPrefs),
focused: true,
child: Stack(
children: [
Align(
child:
Expand All @@ -200,10 +210,14 @@ class _Product extends State<ProductView> {
),
ProductText(product.title)
]
);
)
);

}
return Stack(
return Semantics(
label: ProductTextSemantics(product, suitable, foodPrefs),
focused: true,
child: Stack(
alignment: Alignment.center,
children: [

Expand Down Expand Up @@ -253,6 +267,7 @@ class _Product extends State<ProductView> {
ProductText(product.title),
tooltipOrNot(),
]
)
);
}
Widget tooltipOrNot(){
Expand Down Expand Up @@ -319,6 +334,31 @@ class _Product extends State<ProductView> {
style: const TextStyle(fontSize: 20)),
);
}
String ProductTextSemantics(Product product, YESMAYBENO suitable, List<FoodPreference> foodPrefs){
String string = product.title != ""? product.title : AppLocalizations.of(context)!.product;
if(suitable == YESMAYBENO.yes){
string += AppLocalizations.of(context)!.productsuitable;
}
else if(suitable == YESMAYBENO.maybe){
string += AppLocalizations.of(context)!.productmaybesuitable;
for(var foodPref in foodPrefs){
if(foodPref.suitable == YESMAYBENO.maybe){
string += " ${foodPref.name}";
}
}
}
else if(suitable == YESMAYBENO.no){
string += AppLocalizations.of(context)!.productnotsuitable;
for(var foodPref in foodPrefs){
if(foodPref.suitable == YESMAYBENO.no){
string += " ${foodPref.name}";
}
}
}


return string;
}
YESMAYBENO isSuitable(List<FoodPreference> foodPrefs){
//If one of the foodPrefs is no, the product is not suitable
for (FoodPreference foodPref in foodPrefs) {
Expand Down
146 changes: 77 additions & 69 deletions lib/ScannerScreen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:qr_mobile_vision/qr_camera.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'ProductView.dart';
import 'package:visibility_detector/visibility_detector.dart';

//apply this class on home: attribute at MaterialApp()
class CamScanner extends StatefulWidget{
Expand All @@ -18,6 +19,7 @@ class _CamScanner extends State<CamScanner> {
late String scanresult;
bool calledScreenAlready = false;
List<String> barcodes = List.empty(growable: true);
bool _isVisible = false;

@override
void initState() {
Expand All @@ -38,87 +40,93 @@ class _CamScanner extends State<CamScanner> {
calledScreenAlready = false;
barcodes.clear();
}
print(AppLifecycleState);
}


@override
Widget build(BuildContext context) {
final squareSize = MediaQuery.of(context).size.width * 0.7;
return Stack(
children: [
QrCamera(
qrCodeCallback: (code) {
scanresult = code!;
if(barcodes.length == 2){
if(barcodes[0] == scanresult && barcodes[1]==scanresult){
if (!calledScreenAlready) {
calledScreenAlready = true;
Navigator.push(context, MaterialPageRoute(
builder: (context) =>
ProductView(barcode: code))).then((value) =>
setState(() {
calledScreenAlready = false;
}));
return
VisibilityDetector(
key: Key('camera'),
onVisibilityChanged: (visibilityInfo) {_isVisible = visibilityInfo.visibleFraction > 0;},
child: Stack(
children: [
QrCamera(
qrCodeCallback: (code) {
scanresult = code!;
if(barcodes.length == 2){
if(barcodes[0] == scanresult && barcodes[1]==scanresult){
if (!calledScreenAlready && _isVisible) {
calledScreenAlready = true;
Navigator.push(context, MaterialPageRoute(
builder: (context) =>
ProductView(barcode: code))).then((value) =>
setState(() {
calledScreenAlready = false;
}));
}
}
else{
barcodes.removeAt(0);
barcodes.add(scanresult);
}
}
else{
barcodes.add(scanresult);
}
}
else{
barcodes.removeAt(0);
barcodes.add(scanresult);
}
}
else{
barcodes.add(scanresult);
}


},
formats: const [BarcodeFormats.EAN_13, BarcodeFormats.EAN_8],
onError: (BuildContext context, Object? error){
return Align(
alignment: Alignment.bottomCenter,
child: FractionallySizedBox(
widthFactor: 0.8, // Set the width of the column to 80% of the screen width
heightFactor: 0.3, //
child: Column(
children: [
const Icon(Icons.no_flash, size: 40),
Container(height: 20),
Text(AppLocalizations.of(context)!.cameraNotWorking)
])
),
);
},
),
Positioned.fill(
child: Align(
alignment: Alignment.center,
child: Container(
height: 2,
width: squareSize,
color: Colors.red,
),
},
formats: const [BarcodeFormats.EAN_13, BarcodeFormats.EAN_8],
onError: (BuildContext context, Object? error){
return Align(
alignment: Alignment.bottomCenter,
child: FractionallySizedBox(
widthFactor: 0.8, // Set the width of the column to 80% of the screen width
heightFactor: 0.3, //
child: Column(
children: [
const Icon(Icons.no_flash, size: 40),
Container(height: 20),
Text(AppLocalizations.of(context)!.cameraNotWorking)
])
),
);
},
),
),
Positioned(
top: (MediaQuery.of(context).size.height -squareSize/2) / 2 ,
left: (MediaQuery.of(context).size.width - squareSize) / 2,
child: ClipRect(
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 2,
),
borderRadius: BorderRadius.circular(10),
color: Colors.transparent,
Positioned.fill(
child: Align(
alignment: Alignment.center,
child: Container(
height: 2,
width: squareSize,
color: Colors.red,
),
height: squareSize/2,
width: squareSize,
),
),
Positioned(
top: (MediaQuery.of(context).size.height -squareSize/2) / 2 ,
left: (MediaQuery.of(context).size.width - squareSize) / 2,
child: ClipRect(
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 2,
),
borderRadius: BorderRadius.circular(10),
color: Colors.transparent,
),
height: squareSize/2,
width: squareSize,
),

),
),
],
);
),
),
],
)
);
}
}
15 changes: 13 additions & 2 deletions lib/assets/languages/app_de.arb
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
{
"helloWorld": "Hallo Welt!",
"barcodescannerscreen": "Barcode-Scanner. Scanne ein Produkt",
"pickypal": "Pickypal",
"back":"zurück",
"product": "Produkt",
"preferenceon": " aktiviert",
"preferenceoff": " deaktiviert",
"noProductFound": "Wir konnten leider kein Produkt finden,",
"addProduct": "aber du kannst das Produkt hier hinzufügen!",
"productsuitable": " ist passend für dich",
"productnotsuitable": " ist nicht passend für dich, denn es ist nicht ",
"productmaybesuitable": " ist vielleicht passend für dich, denn es ist vielleicht nicht ",
"settings": "Einstellungen",
"settingsbuttonsemantics": "Einstellungen",
"common": "Allgemein",
"funding": "Finanzierung",
"pleaseFund": "Bitte unterstütze mich, indem du die App finanziert.",
"cameraNotWorking": "Die Kamera funktioniert leider nicht richtig. Versuche, die App zuzustarten!",
"cameraNotWorking": "Die Kamera funktioniert leider nicht richtig. Versuche, die App neuzustarten!",
"cancel": "Abbrechen!",
"ok": "Ok",
"vegan": "Vegan",
Expand All @@ -19,5 +29,6 @@
"soyFree": "Sojafrei",
"glutamateFree": "Glutamatfrei",
"carbohydrates": "Kohlenhydrate",
"carbohydrateslimit": "g/100g"
"carbohydrateslimit": "g/100g",
"carbohydrateslimitsemantics": "gramm pro 100g"
}
Loading

0 comments on commit 2120c7d

Please sign in to comment.