Compare commits

..

No commits in common. "1f99e729057d08a8b7e071460c75ee3230e3c236" and "243047a1f73e0f061c1a0e2c263e63bb484bd9e2" have entirely different histories.

13 changed files with 54 additions and 104 deletions

2
.gitignore vendored
View file

@ -57,6 +57,6 @@ keystore.properties
android/app/google-services.json android/app/google-services.json
ios/firebase_app_id_file.json ios/firebase_app_id_file.json
ios/Runner/GoogleService-Info.plist ios/Runner/GoogleService-Info.plist
/lib/firebase_options.dart lib/firebase_options.dart
coverage/ coverage/

66
.vscode/launch.json vendored
View file

@ -5,10 +5,9 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "dev-debug (android)", "name": "dev (android)",
"request": "launch", "request": "launch",
"type": "dart", "type": "dart",
"flutterMode": "debug",
"args": [ "args": [
"--flavor", "--flavor",
"dev", "dev",
@ -18,49 +17,9 @@
"program": "${workspaceFolder}/lib/main_dev.dart", "program": "${workspaceFolder}/lib/main_dev.dart",
}, },
{ {
"name": "dev-profile (android)", "name": "dev (ios)",
"request": "launch", "request": "launch",
"type": "dart", "type": "dart",
"flutterMode": "profile",
"args": [
"--flavor",
"dev",
"--dart-define",
"cameraPreviewAspectRatio=240/320",
],
"program": "${workspaceFolder}/lib/main_dev.dart",
},
{
"name": "prod-debug (android)",
"request": "launch",
"type": "dart",
"flutterMode": "debug",
"args": [
"--flavor",
"prod",
"--dart-define",
"cameraPreviewAspectRatio=240/320",
],
"program": "${workspaceFolder}/lib/main_release.dart",
},
{
"name": "prod-profile (android)",
"request": "launch",
"type": "dart",
"flutterMode": "profile",
"args": [
"--flavor",
"prod",
"--dart-define",
"cameraPreviewAspectRatio=240/320",
],
"program": "${workspaceFolder}/lib/main_release.dart",
},
{
"name": "dev-debug (ios)",
"request": "launch",
"type": "dart",
"flutterMode": "debug",
"args": [ "args": [
"--flavor", "--flavor",
"dev", "dev",
@ -70,17 +29,30 @@
"program": "${workspaceFolder}/lib/main_dev.dart", "program": "${workspaceFolder}/lib/main_dev.dart",
}, },
{ {
"name": "dev-profile (ios)", "name": "prod (android)",
"request": "launch", "request": "launch",
"flutterMode": "profile", //"flutterMode": "release",
"type": "dart", "type": "dart",
"args": [ "args": [
"--flavor", "--flavor",
"dev", "prod",
"--dart-define",
"cameraPreviewAspectRatio=240/320",
],
"program": "${workspaceFolder}/lib/main_prod.dart",
},
{
"name": "prod (ios)",
"request": "launch",
//"flutterMode": "release",
"type": "dart",
"args": [
"--flavor",
"prod",
"--dart-define", "--dart-define",
"cameraPreviewAspectRatio=3/4", "cameraPreviewAspectRatio=3/4",
], ],
"program": "${workspaceFolder}/lib/main_dev.dart", "program": "${workspaceFolder}/lib/main_prod.dart",
}, },
], ],
} }

View file

@ -60,18 +60,13 @@ flutter pub get
flutter pub run intl_utils:generate flutter pub run intl_utils:generate
``` ```
### 4. Build ### 4. Build (Android)
#### Android
You can build an apk by running the following command from the root of the repository: You can build an apk by running the following command from the root of the repository:
```console ```console
flutter build apk --release --flavor dev --dart-define cameraPreviewAspectRatio=240/320 -t lib/main_dev.dart flutter build apk --release --flavor $FLAVOR --dart-define cameraPreviewAspectRatio=240/320 -t lib/main_$FLAVOR.dart
``` ```
Just replace `$FLAVOR` with `dev` or `prod`.
### iOS
TBD
# Contribution # Contribution

View file

@ -1,22 +1,14 @@
import 'dart:developer';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:lightmeter/firebase_options.dart'; import 'package:lightmeter/firebase_options.dart';
Future<void> initializeFirebase({required bool handleErrors}) async { Future<void> initializeFirebase() async {
try {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
if (handleErrors) {
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError; FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
PlatformDispatcher.instance.onError = (error, stack) { PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true); FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true; return true;
}; };
} }
} catch (e) {
log(e.toString());
}
}

View file

@ -36,7 +36,6 @@
"lightSensor": "Light sensor", "lightSensor": "Light sensor",
"meteringScreenLayout": "Metering screen layout", "meteringScreenLayout": "Metering screen layout",
"meteringScreenLayoutHint": "Hide elements on the metering screen that you don't need so that they don't waste exposure pairs list space.", "meteringScreenLayoutHint": "Hide elements on the metering screen that you don't need so that they don't waste exposure pairs list space.",
"meteringScreenLayoutHintEquipmentProfiles": "Equipment profile picker",
"meteringScreenFeatureExtremeExposurePairs": "Fastest & shortest exposure pairs", "meteringScreenFeatureExtremeExposurePairs": "Fastest & shortest exposure pairs",
"meteringScreenFeatureFilmPicker": "Film picker", "meteringScreenFeatureFilmPicker": "Film picker",
"meteringScreenFeatureHistogram": "Histogram", "meteringScreenFeatureHistogram": "Histogram",

View file

@ -36,7 +36,6 @@
"lightSensor": "Capteur de lumière", "lightSensor": "Capteur de lumière",
"meteringScreenLayout": "Disposition de l'écran de mesure", "meteringScreenLayout": "Disposition de l'écran de mesure",
"meteringScreenLayoutHint": "Masquer les éléments sur l'écran de mesure dont vous n'avez pas besoin pour qu'ils ne gaspillent pas de l'espace dans les paires d'exposition.", "meteringScreenLayoutHint": "Masquer les éléments sur l'écran de mesure dont vous n'avez pas besoin pour qu'ils ne gaspillent pas de l'espace dans les paires d'exposition.",
"meteringScreenLayoutHintEquipmentProfiles": "Sélecteur de profil de l'équipement",
"meteringScreenFeatureExtremeExposurePairs": "Paires d'exposition les plus rapides et les plus courtes", "meteringScreenFeatureExtremeExposurePairs": "Paires d'exposition les plus rapides et les plus courtes",
"meteringScreenFeatureFilmPicker": "Sélecteur de film", "meteringScreenFeatureFilmPicker": "Sélecteur de film",
"meteringScreenFeatureHistogram": "Histogramme", "meteringScreenFeatureHistogram": "Histogramme",

View file

@ -36,7 +36,6 @@
"lightSensor": "Датчик освещённости", "lightSensor": "Датчик освещённости",
"meteringScreenLayout": "Элементы главного экрана", "meteringScreenLayout": "Элементы главного экрана",
"meteringScreenLayoutHint": "Здесь вы можете скрыть некоторые ненужные или неиспользуемые элементы с главного экрана.", "meteringScreenLayoutHint": "Здесь вы можете скрыть некоторые ненужные или неиспользуемые элементы с главного экрана.",
"meteringScreenLayoutHintEquipmentProfiles": "Выбор профиля оборудования",
"meteringScreenFeatureExtremeExposurePairs": "Длинная и короткая выдержки", "meteringScreenFeatureExtremeExposurePairs": "Длинная и короткая выдержки",
"meteringScreenFeatureFilmPicker": "Выбор пленки", "meteringScreenFeatureFilmPicker": "Выбор пленки",
"meteringScreenFeatureHistogram": "Гистограмма", "meteringScreenFeatureHistogram": "Гистограмма",

View file

@ -36,7 +36,6 @@
"lightSensor": "光传感器", "lightSensor": "光传感器",
"meteringScreenLayout": "布局", "meteringScreenLayout": "布局",
"meteringScreenLayoutHint": "隐藏不需要的元素,以免浪费曝光列表空间", "meteringScreenLayoutHint": "隐藏不需要的元素,以免浪费曝光列表空间",
"meteringScreenLayoutHintEquipmentProfiles": "设备配置选择",
"meteringScreenFeatureExtremeExposurePairs": "最快 & 最慢曝光组合", "meteringScreenFeatureExtremeExposurePairs": "最快 & 最慢曝光组合",
"meteringScreenFeatureFilmPicker": "胶片选择", "meteringScreenFeatureFilmPicker": "胶片选择",
"meteringScreenFeatureHistogram": "直方图", "meteringScreenFeatureHistogram": "直方图",

View file

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lightmeter/application.dart'; import 'package:lightmeter/application.dart';
import 'package:lightmeter/environment.dart'; import 'package:lightmeter/environment.dart';
@ -5,6 +7,10 @@ import 'package:lightmeter/firebase.dart';
Future<void> main() async { Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await initializeFirebase(handleErrors: true); try {
await initializeFirebase();
} catch (e) {
log(e.toString());
}
runApp(const Application(Environment.prod())); runApp(const Application(Environment.prod()));
} }

View file

@ -1,10 +0,0 @@
import 'package:flutter/material.dart';
import 'package:lightmeter/application.dart';
import 'package:lightmeter/environment.dart';
import 'package:lightmeter/firebase.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await initializeFirebase(handleErrors: false);
runApp(const Application(Environment.prod()));
}

View file

@ -84,8 +84,16 @@ class _InheritedListeners extends StatelessWidget {
context.read<MeteringBloc>().add(const FilmChangedEvent(Film.other())); context.read<MeteringBloc>().add(const FilmChangedEvent(Film.other()));
} }
}, },
child: MeteringScreenLayoutFeatureListener(
feature: MeteringScreenLayoutFeature.equipmentProfiles,
onDidChangeDependencies: (value) {
if (!value) {
EquipmentProfileProvider.of(context).setProfile(EquipmentProfiles.of(context).first);
}
},
child: child, child: child,
), ),
),
); );
} }
} }

View file

@ -3,7 +3,6 @@ import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
import 'package:lightmeter/generated/l10n.dart'; import 'package:lightmeter/generated/l10n.dart';
import 'package:lightmeter/providers/user_preferences_provider.dart'; import 'package:lightmeter/providers/user_preferences_provider.dart';
import 'package:lightmeter/res/dimens.dart'; import 'package:lightmeter/res/dimens.dart';
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
class MeteringScreenLayoutFeaturesDialog extends StatefulWidget { class MeteringScreenLayoutFeaturesDialog extends StatefulWidget {
const MeteringScreenLayoutFeaturesDialog({super.key}); const MeteringScreenLayoutFeaturesDialog({super.key});
@ -26,25 +25,20 @@ class _MeteringScreenLayoutFeaturesDialogState extends State<MeteringScreenLayou
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
content: SizedBox( content: SizedBox(
width: double.maxFinite, width: double.maxFinite,
child: Column( child: ListView(
mainAxisSize: MainAxisSize.min, shrinkWrap: true,
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: Dimens.paddingL), padding: const EdgeInsets.symmetric(horizontal: Dimens.paddingL),
child: Text(S.of(context).meteringScreenLayoutHint), child: Text(S.of(context).meteringScreenLayoutHint),
), ),
const SizedBox(height: Dimens.grid16), const SizedBox(height: Dimens.grid16),
ListView(
shrinkWrap: true,
children: [
_featureListTile(MeteringScreenLayoutFeature.equipmentProfiles), _featureListTile(MeteringScreenLayoutFeature.equipmentProfiles),
_featureListTile(MeteringScreenLayoutFeature.extremeExposurePairs), _featureListTile(MeteringScreenLayoutFeature.extremeExposurePairs),
_featureListTile(MeteringScreenLayoutFeature.filmPicker), _featureListTile(MeteringScreenLayoutFeature.filmPicker),
_featureListTile(MeteringScreenLayoutFeature.histogram), _featureListTile(MeteringScreenLayoutFeature.histogram),
], ],
), ),
],
),
), ),
actionsPadding: Dimens.dialogActionsPadding, actionsPadding: Dimens.dialogActionsPadding,
actions: [ actions: [
@ -54,9 +48,6 @@ class _MeteringScreenLayoutFeaturesDialogState extends State<MeteringScreenLayou
), ),
TextButton( TextButton(
onPressed: () { onPressed: () {
if (!_features[MeteringScreenLayoutFeature.equipmentProfiles]!) {
EquipmentProfileProvider.of(context).setProfile(EquipmentProfiles.of(context).first);
}
UserPreferencesProvider.of(context).setMeteringScreenLayout(_features); UserPreferencesProvider.of(context).setMeteringScreenLayout(_features);
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
@ -82,7 +73,7 @@ class _MeteringScreenLayoutFeaturesDialogState extends State<MeteringScreenLayou
String _toStringLocalized(BuildContext context, MeteringScreenLayoutFeature feature) { String _toStringLocalized(BuildContext context, MeteringScreenLayoutFeature feature) {
switch (feature) { switch (feature) {
case MeteringScreenLayoutFeature.equipmentProfiles: case MeteringScreenLayoutFeature.equipmentProfiles:
return S.of(context).meteringScreenLayoutHintEquipmentProfiles; return S.of(context).equipmentProfiles;
case MeteringScreenLayoutFeature.extremeExposurePairs: case MeteringScreenLayoutFeature.extremeExposurePairs:
return S.of(context).meteringScreenFeatureExtremeExposurePairs; return S.of(context).meteringScreenFeatureExtremeExposurePairs;
case MeteringScreenLayoutFeature.filmPicker: case MeteringScreenLayoutFeature.filmPicker:

View file

@ -1,7 +1,7 @@
name: lightmeter name: lightmeter
description: Lightmeter app inspired by Material 3 design system. description: Lightmeter app inspired by Material 3 design system.
publish_to: "none" publish_to: "none"
version: 0.14.0+39 version: 0.13.2+38
environment: environment:
sdk: ">=3.0.0 <4.0.0" sdk: ">=3.0.0 <4.0.0"