mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2025-07-06 14:10:41 +00:00
Compare commits
6 commits
243047a1f7
...
1f99e72905
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1f99e72905 | ||
![]() |
46ee72174f | ||
![]() |
16c81a7116 | ||
![]() |
4201d36abb | ||
![]() |
429c0a53a2 | ||
![]() |
f39177919c |
13 changed files with 104 additions and 54 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -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
66
.vscode/launch.json
vendored
|
@ -5,9 +5,10 @@
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "dev (android)",
|
"name": "dev-debug (android)",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"type": "dart",
|
"type": "dart",
|
||||||
|
"flutterMode": "debug",
|
||||||
"args": [
|
"args": [
|
||||||
"--flavor",
|
"--flavor",
|
||||||
"dev",
|
"dev",
|
||||||
|
@ -17,9 +18,49 @@
|
||||||
"program": "${workspaceFolder}/lib/main_dev.dart",
|
"program": "${workspaceFolder}/lib/main_dev.dart",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "dev (ios)",
|
"name": "dev-profile (android)",
|
||||||
"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",
|
||||||
|
@ -29,30 +70,17 @@
|
||||||
"program": "${workspaceFolder}/lib/main_dev.dart",
|
"program": "${workspaceFolder}/lib/main_dev.dart",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "prod (android)",
|
"name": "dev-profile (ios)",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
//"flutterMode": "release",
|
"flutterMode": "profile",
|
||||||
"type": "dart",
|
"type": "dart",
|
||||||
"args": [
|
"args": [
|
||||||
"--flavor",
|
"--flavor",
|
||||||
"prod",
|
"dev",
|
||||||
"--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_prod.dart",
|
"program": "${workspaceFolder}/lib/main_dev.dart",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
11
README.md
11
README.md
|
@ -60,13 +60,18 @@ flutter pub get
|
||||||
flutter pub run intl_utils:generate
|
flutter pub run intl_utils:generate
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Build (Android)
|
### 4. Build
|
||||||
|
|
||||||
|
#### 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 $FLAVOR --dart-define cameraPreviewAspectRatio=240/320 -t lib/main_$FLAVOR.dart
|
flutter build apk --release --flavor dev --dart-define cameraPreviewAspectRatio=240/320 -t lib/main_dev.dart
|
||||||
```
|
```
|
||||||
Just replace `$FLAVOR` with `dev` or `prod`.
|
|
||||||
|
### iOS
|
||||||
|
|
||||||
|
TBD
|
||||||
|
|
||||||
# Contribution
|
# Contribution
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,22 @@
|
||||||
|
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() async {
|
Future<void> initializeFirebase({required bool handleErrors}) async {
|
||||||
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
|
try {
|
||||||
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
|
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
|
||||||
PlatformDispatcher.instance.onError = (error, stack) {
|
if (handleErrors) {
|
||||||
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
|
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
|
||||||
return true;
|
PlatformDispatcher.instance.onError = (error, stack) {
|
||||||
};
|
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log(e.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
"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",
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
"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",
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
"lightSensor": "Датчик освещённости",
|
"lightSensor": "Датчик освещённости",
|
||||||
"meteringScreenLayout": "Элементы главного экрана",
|
"meteringScreenLayout": "Элементы главного экрана",
|
||||||
"meteringScreenLayoutHint": "Здесь вы можете скрыть некоторые ненужные или неиспользуемые элементы с главного экрана.",
|
"meteringScreenLayoutHint": "Здесь вы можете скрыть некоторые ненужные или неиспользуемые элементы с главного экрана.",
|
||||||
|
"meteringScreenLayoutHintEquipmentProfiles": "Выбор профиля оборудования",
|
||||||
"meteringScreenFeatureExtremeExposurePairs": "Длинная и короткая выдержки",
|
"meteringScreenFeatureExtremeExposurePairs": "Длинная и короткая выдержки",
|
||||||
"meteringScreenFeatureFilmPicker": "Выбор пленки",
|
"meteringScreenFeatureFilmPicker": "Выбор пленки",
|
||||||
"meteringScreenFeatureHistogram": "Гистограмма",
|
"meteringScreenFeatureHistogram": "Гистограмма",
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
"lightSensor": "光传感器",
|
"lightSensor": "光传感器",
|
||||||
"meteringScreenLayout": "布局",
|
"meteringScreenLayout": "布局",
|
||||||
"meteringScreenLayoutHint": "隐藏不需要的元素,以免浪费曝光列表空间",
|
"meteringScreenLayoutHint": "隐藏不需要的元素,以免浪费曝光列表空间",
|
||||||
|
"meteringScreenLayoutHintEquipmentProfiles": "设备配置选择",
|
||||||
"meteringScreenFeatureExtremeExposurePairs": "最快 & 最慢曝光组合",
|
"meteringScreenFeatureExtremeExposurePairs": "最快 & 最慢曝光组合",
|
||||||
"meteringScreenFeatureFilmPicker": "胶片选择",
|
"meteringScreenFeatureFilmPicker": "胶片选择",
|
||||||
"meteringScreenFeatureHistogram": "直方图",
|
"meteringScreenFeatureHistogram": "直方图",
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
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';
|
||||||
|
@ -7,10 +5,6 @@ import 'package:lightmeter/firebase.dart';
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
try {
|
await initializeFirebase(handleErrors: true);
|
||||||
await initializeFirebase();
|
|
||||||
} catch (e) {
|
|
||||||
log(e.toString());
|
|
||||||
}
|
|
||||||
runApp(const Application(Environment.prod()));
|
runApp(const Application(Environment.prod()));
|
||||||
}
|
}
|
||||||
|
|
10
lib/main_release.dart
Normal file
10
lib/main_release.dart
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
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()));
|
||||||
|
}
|
|
@ -84,15 +84,7 @@ class _InheritedListeners extends StatelessWidget {
|
||||||
context.read<MeteringBloc>().add(const FilmChangedEvent(Film.other()));
|
context.read<MeteringBloc>().add(const FilmChangedEvent(Film.other()));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: MeteringScreenLayoutFeatureListener(
|
child: child,
|
||||||
feature: MeteringScreenLayoutFeature.equipmentProfiles,
|
|
||||||
onDidChangeDependencies: (value) {
|
|
||||||
if (!value) {
|
|
||||||
EquipmentProfileProvider.of(context).setProfile(EquipmentProfiles.of(context).first);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ 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});
|
||||||
|
@ -25,18 +26,23 @@ class _MeteringScreenLayoutFeaturesDialogState extends State<MeteringScreenLayou
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
content: SizedBox(
|
content: SizedBox(
|
||||||
width: double.maxFinite,
|
width: double.maxFinite,
|
||||||
child: ListView(
|
child: Column(
|
||||||
shrinkWrap: true,
|
mainAxisSize: MainAxisSize.min,
|
||||||
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),
|
||||||
_featureListTile(MeteringScreenLayoutFeature.equipmentProfiles),
|
ListView(
|
||||||
_featureListTile(MeteringScreenLayoutFeature.extremeExposurePairs),
|
shrinkWrap: true,
|
||||||
_featureListTile(MeteringScreenLayoutFeature.filmPicker),
|
children: [
|
||||||
_featureListTile(MeteringScreenLayoutFeature.histogram),
|
_featureListTile(MeteringScreenLayoutFeature.equipmentProfiles),
|
||||||
|
_featureListTile(MeteringScreenLayoutFeature.extremeExposurePairs),
|
||||||
|
_featureListTile(MeteringScreenLayoutFeature.filmPicker),
|
||||||
|
_featureListTile(MeteringScreenLayoutFeature.histogram),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -48,6 +54,9 @@ 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();
|
||||||
},
|
},
|
||||||
|
@ -73,7 +82,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).equipmentProfiles;
|
return S.of(context).meteringScreenLayoutHintEquipmentProfiles;
|
||||||
case MeteringScreenLayoutFeature.extremeExposurePairs:
|
case MeteringScreenLayoutFeature.extremeExposurePairs:
|
||||||
return S.of(context).meteringScreenFeatureExtremeExposurePairs;
|
return S.of(context).meteringScreenFeatureExtremeExposurePairs;
|
||||||
case MeteringScreenLayoutFeature.filmPicker:
|
case MeteringScreenLayoutFeature.filmPicker:
|
||||||
|
|
|
@ -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.13.2+38
|
version: 0.14.0+39
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.0.0 <4.0.0"
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
|
|
Loading…
Reference in a new issue