Skip to content

Commit

Permalink
Merge branch 'develop' into issue-openfoodfacts#1667
Browse files Browse the repository at this point in the history
  • Loading branch information
vik4114 committed May 7, 2022
2 parents e592586 + 6752395 commit 1349180
Show file tree
Hide file tree
Showing 164 changed files with 1,460 additions and 428 deletions.
14 changes: 10 additions & 4 deletions .github/pull_request_template.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
### What
- description of the PR
<!-- description of the PR -->
- Changed x to achieve y

### Screenshot
(Insert a screenshot to provide visual record of your changes, if visible)
<!-- Insert a screenshot to provide visual record of your changes, if visible -->

### Fixes bug(s)
- #1, #2 and #3 (change by appropriate issues)
<!-- change by appropriate issues. -->
<!-- Please use a linking keyword https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword -->
- Fixes: #1
- Closes: #2

### Part of
- https://github.com/openfoodfacts/smooth-app/issues/525
(please be as granular as possible)
<!-- please be as granular as possible -->
2 changes: 1 addition & 1 deletion .github/workflows/android-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
run: echo ${{ env.RELEASE_VERSION }}

- name: Setup Java JDK
uses: actions/setup-java@v3.2.0
uses: actions/setup-java@v3.3.0
with:
distribution: 'zulu'
java-version: 11
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/crowdin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
uses: actions/checkout@v3

- name: crowdin action
uses: crowdin/github-action@1.4.8
uses: crowdin/github-action@1.4.9
continue-on-error: true
with:
# Upload sources to Crowdin
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ios-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
ruby-version: 3.0.2

- name: Setup Java JDK
uses: actions/setup-java@v3.2.0
uses: actions/setup-java@v3.3.0
with:
distribution: 'zulu'
java-version: 11
Expand All @@ -36,7 +36,7 @@ jobs:
with:
channel: stable
cache: true
cache-key: flutter2.10 #change this to force refresh cache
cache-key: flutter2.10 # change this to force refresh cache
- run: flutter --version

- name: Get dependencies
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/postsubmit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
uses: actions/checkout@v3

- name: Setup Java JDK
uses: actions/setup-java@v3.2.0
uses: actions/setup-java@v3.3.0
with:
distribution: 'zulu'
java-version: 11
Expand Down
2 changes: 1 addition & 1 deletion packages/smooth_app/ios/Runner/fr.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"NSCameraUsageDescription" = "This app needs camera access to scan barcodes and to take product photos";
"NSCameraUsageDescription" = "Cette application a besoin d'un accès à l'appareil photo pour scanner des codes à barres et pour prendre des photos de produits";
2 changes: 1 addition & 1 deletion packages/smooth_app/ios/fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ setup_travis
default_platform(:ios)

before_all do
xcversion(version: "~> 12.3")
xcversion(version: "~> 13.3")
end

platform :ios do
Expand Down
38 changes: 26 additions & 12 deletions packages/smooth_app/lib/cards/product_cards/product_title_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:smooth_app/data_models/continuous_scan_model.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/helpers/extension_on_text_helper.dart';
import 'package:smooth_app/helpers/product_cards_helper.dart';
import 'package:smooth_app/pages/product/add_basic_details_page.dart';

class ProductTitleCard extends StatelessWidget {
const ProductTitleCard(
Expand All @@ -28,7 +29,7 @@ class ProductTitleCard extends StatelessWidget {
final Widget trailingWidget;
final String brands = product.brands ?? appLocalizations.unknownBrand;
final String quantity = product.quantity ?? '';
if (isRemovable) {
if (isRemovable && !isSelectable) {
final ContinuousScanModel model = context.watch<ContinuousScanModel>();
subtitleText = '$brands${quantity == '' ? '' : ', $quantity'}';
trailingWidget = InkWell(
Expand All @@ -47,17 +48,30 @@ class ProductTitleCard extends StatelessWidget {
}
return Align(
alignment: Alignment.topLeft,
child: ListTile(
dense: dense,
contentPadding: EdgeInsets.zero,
title: Text(
getProductName(product, appLocalizations),
style: themeData.textTheme.headline4,
).selectable(isSelectable: isSelectable),
subtitle: Text(
subtitleText,
).selectable(isSelectable: isSelectable),
trailing: trailingWidget,
child: InkWell(
onTap: () async {
if (getProductName(product, appLocalizations) ==
appLocalizations.unknownProductName) {
await Navigator.push<bool>(
context,
MaterialPageRoute<bool>(
builder: (BuildContext context) => AddBasicDetailsPage(product),
),
);
}
},
child: ListTile(
dense: dense,
contentPadding: EdgeInsets.zero,
title: Text(
getProductName(product, appLocalizations),
style: themeData.textTheme.headline4,
).selectable(isSelectable: isSelectable),
subtitle: Text(
subtitleText,
).selectable(isSelectable: isSelectable),
trailing: trailingWidget,
),
),
);
}
Expand Down
27 changes: 11 additions & 16 deletions packages/smooth_app/lib/data_models/product_preferences.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import 'package:openfoodfacts/model/AttributeGroup.dart';
import 'package:openfoodfacts/personalized_search/available_attribute_groups.dart';
import 'package:openfoodfacts/personalized_search/available_preference_importances.dart';
import 'package:openfoodfacts/personalized_search/available_product_preferences.dart';
import 'package:openfoodfacts/personalized_search/preference_importance.dart';
import 'package:openfoodfacts/personalized_search/product_preferences_manager.dart';
import 'package:openfoodfacts/personalized_search/product_preferences_selection.dart';
import 'package:smooth_app/data_models/downloadable_string.dart';
Expand Down Expand Up @@ -109,19 +108,25 @@ class ProductPreferences extends ProductPreferencesManager with ChangeNotifier {
/// The downloaded strings are automatically stored in the database.
Future<bool> _loadFromNetwork(String languageCode) async {
try {
final bool differentLanguages;
if (daoString != null) {
final String? latestLanguage =
await daoString!.get(_DAO_STRING_KEY_LANGUAGE);
differentLanguages = latestLanguage != languageCode;
} else {
differentLanguages = true;
}
final String importanceUrl =
AvailablePreferenceImportances.getUrl(languageCode);
final String attributeGroupUrl =
AvailableAttributeGroups.getUrl(languageCode);
final DownloadableString downloadableImportance;
downloadableImportance =
final DownloadableString downloadableImportance =
DownloadableString(Uri.parse(importanceUrl), dao: daoString);
final bool differentImportance = await downloadableImportance.download();
final DownloadableString downloadableAttributes =
DownloadableString(Uri.parse(attributeGroupUrl), dao: daoString);
final bool differentAttributes = await downloadableAttributes.download();
// the downloaded values are identical to what was stored locally.
if ((!differentImportance) && (!differentAttributes)) {
if (!(differentImportance || differentAttributes || differentLanguages)) {
return false;
}
final String preferenceImportancesString = downloadableImportance.value!;
Expand Down Expand Up @@ -182,16 +187,6 @@ class ProductPreferences extends ProductPreferencesManager with ChangeNotifier {
availableProductPreferences = myAvailableProductPreferences;
}

@override
String getImportanceIdForAttributeId(String attributeId) =>
_getRefinedImportanceId(super.getImportanceIdForAttributeId(attributeId));

/// Downgrades "very important" to "important" (from 4 to 3 choices, simpler).
static String _getRefinedImportanceId(final String importanceId) =>
importanceId == PreferenceImportance.ID_VERY_IMPORTANT
? PreferenceImportance.ID_IMPORTANT
: importanceId;

Future<void> resetImportances() async {
await clearImportances(notifyListeners: false);
if (attributeGroups != null) {
Expand All @@ -202,7 +197,7 @@ class ProductPreferences extends ProductPreferencesManager with ChangeNotifier {
if (attribute.id != null && defaultF != null) {
await setImportance(
attribute.id!,
_getRefinedImportanceId(defaultF),
defaultF,
notifyListeners: false,
);
}
Expand Down
29 changes: 17 additions & 12 deletions packages/smooth_app/lib/data_models/user_management_provider.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:openfoodfacts/utils/OpenFoodAPIConfiguration.dart';
import 'package:smooth_app/database/dao_secured_string.dart';
Expand All @@ -7,10 +8,6 @@ class UserManagementProvider with ChangeNotifier {
static const String _USER_ID = 'user_id';
static const String _PASSWORD = 'pasword';

bool _finishedLoading = false;

bool get isLoading => !_finishedLoading;

/// Checks credentials and conditionally saves them
Future<bool> login(User user) async {
final bool rightCredentials;
Expand All @@ -22,6 +19,7 @@ class UserManagementProvider with ChangeNotifier {

if (rightCredentials) {
await putUser(user);
notifyListeners();
}

return rightCredentials && await credentialsInStorage();
Expand All @@ -38,20 +36,27 @@ class UserManagementProvider with ChangeNotifier {
}

/// Mounts already stored credentials, called at app startup
Future<void> mountCredentials() async {
final String? userId = await DaoSecuredString.get(_USER_ID);
final String? password = await DaoSecuredString.get(_PASSWORD);
static Future<void> mountCredentials() async {
String? userId;
String? password;

try {
userId = await DaoSecuredString.get(_USER_ID);
password = await DaoSecuredString.get(_PASSWORD);
} on PlatformException {
/// Decrypting the values can go wrong if, for example, the app was
/// manually overwritten from an external apk.
DaoSecuredString.remove(key: _USER_ID);
DaoSecuredString.remove(key: _PASSWORD);
debugPrint('Credentials query failed, you have been logged out');
}

if (userId == null || password == null) {
_finishedLoading = true;
notifyListeners();
return;
}

final User user = User(userId: userId, password: password);
OpenFoodAPIConfiguration.globalUser = user;
_finishedLoading = true;
notifyListeners();
}

/// Checks if any credentials exist in storage
Expand Down
6 changes: 6 additions & 0 deletions packages/smooth_app/lib/generic_lib/design_constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ const double LARGE_SPACE = 16.0;
const double VERY_LARGE_SPACE = 20.0;
const double MINIMUM_TOUCH_SIZE = 48.0;

/// Default icon size, cf. [Icon]
const double DEFAULT_ICON_SIZE = 24.0;

/// Default icon size, cf. goldens.dart
const double MINIMUM_TARGET_SIZE = 48.0;

/// Background, e.g SmoothCard
const Radius ROUNDED_RADIUS = Radius.circular(20.0);
//ignore: non_constant_identifier_names
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class SmoothTextFormField extends StatefulWidget {
this.hintTextFontSize,
this.prefixIcon,
this.textInputType,
this.onChanged,
}) : super(key: key);

final TextFieldTypes type;
Expand All @@ -35,6 +36,7 @@ class SmoothTextFormField extends StatefulWidget {
final double? hintTextFontSize;
final Color? backgroundColor;
final TextInputType? textInputType;
final void Function(String?)? onChanged;

@override
State<SmoothTextFormField> createState() => _SmoothTextFormFieldState();
Expand Down Expand Up @@ -65,16 +67,17 @@ class _SmoothTextFormFieldState extends State<SmoothTextFormField> {
autocorrect: _autocorrect,
autofillHints: widget.autofillHints,
autovalidateMode: AutovalidateMode.onUserInteraction,
onChanged: (String data) {
// Rebuilds for changing the eye icon
if (widget.type == TextFieldTypes.PASSWORD) {
if (data.isEmpty) {
setState(() {});
} else if (data.isNotEmpty && data.length > 1) {
setState(() {});
}
}
},
onChanged: widget.onChanged ??
(String data) {
// Rebuilds for changing the eye icon
if (widget.type == TextFieldTypes.PASSWORD) {
if (data.isEmpty) {
setState(() {});
} else if (data.isNotEmpty && data.length > 1) {
setState(() {});
}
}
},
decoration: InputDecoration(
prefixIcon: widget.prefixIcon,
filled: true,
Expand Down
51 changes: 51 additions & 0 deletions packages/smooth_app/lib/helpers/camera_helper.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import 'package:camera/camera.dart';

class CameraHelper {
const CameraHelper._();

static List<CameraDescription>? _cameras;

/// Mandatory method to call before [findBestCamera]
static Future<void> init() async {
_cameras = await availableCameras();
}

/// Find the most relevant camera to use if none of these criteria are met,
/// the default value of [_cameraIndex] will be used to select the first
/// camera in the global cameras list.
/// if non matching is found we fall back to the first in the list
/// initValue of [_cameraIndex]/
static CameraDescription? findBestCamera({
CameraLensDirection cameraLensDirection = CameraLensDirection.back,
}) {
if (_cameras == null) {
throw Exception('Please call [init] before!');
} else if (_cameras!.isEmpty) {
return null;
}

int cameraIndex = -1;

if (_cameras!.any(
(CameraDescription element) =>
element.lensDirection == cameraLensDirection &&
element.sensorOrientation == 90,
)) {
cameraIndex = _cameras!.indexOf(
_cameras!.firstWhere((CameraDescription element) =>
element.lensDirection == cameraLensDirection &&
element.sensorOrientation == 90),
);
} else if (_cameras!.any((CameraDescription element) =>
element.lensDirection == cameraLensDirection)) {
cameraIndex = _cameras!.indexOf(
_cameras!.firstWhere(
(CameraDescription element) =>
element.lensDirection == cameraLensDirection,
),
);
}

return _cameras![cameraIndex];
}
}
6 changes: 2 additions & 4 deletions packages/smooth_app/lib/helpers/picture_capture_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:provider/provider.dart';
import 'package:smooth_app/data_models/continuous_scan_model.dart';
import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/database/product_query.dart';
import 'package:smooth_app/generic_lib/loading_dialog.dart';

Expand Down Expand Up @@ -41,7 +40,6 @@ Future<bool> uploadCapturedPicture(

Future<void> _updateContinuousScanModel(
BuildContext context, String barcode) async {
final ContinuousScanModel? model =
await ContinuousScanModel().load(context.read<LocalDatabase>());
await model?.onCreateProduct(barcode);
final ContinuousScanModel model = context.read<ContinuousScanModel>();
await model.onCreateProduct(barcode);
}
4 changes: 4 additions & 0 deletions packages/smooth_app/lib/l10n/app_aa.arb
Original file line number Diff line number Diff line change
Expand Up @@ -888,5 +888,9 @@
"user_list_name_error_same": "That is the same name",
"@user_list_name_error_same": {
"description": "Validation error about the renamed name that is the same as the initial list name"
},
"confirm_clear": "Do you really want to clear?",
"@confirm_clear": {
"description": "Asking about whether to clear the list or not"
}
}
Loading

0 comments on commit 1349180

Please sign in to comment.