mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2025-07-08 07:00:40 +00:00
Compare commits
No commits in common. "f49679353d5c5ab23c6fcdf702ea097a8a432e48" and "eeb70bfaff66f60d1ba782dbb1a094294c0ffdb6" have entirely different histories.
f49679353d
...
eeb70bfaff
13 changed files with 30 additions and 63 deletions
9
.github/workflows/pr_check.yml
vendored
9
.github/workflows/pr_check.yml
vendored
|
@ -15,7 +15,7 @@ jobs:
|
||||||
analyze_and_test:
|
analyze_and_test:
|
||||||
name: Analyze & test
|
name: Analyze & test
|
||||||
runs-on: macos-11
|
runs-on: macos-11
|
||||||
timeout-minutes: 5
|
timeout-minutes: 10
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
|
@ -47,10 +47,3 @@ jobs:
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: flutter test
|
run: flutter test
|
||||||
|
|
||||||
- name: Analyze project source with stub
|
|
||||||
if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
|
|
||||||
run: |
|
|
||||||
bash ./.github/scripts/stub_iap.sh
|
|
||||||
flutter pub get
|
|
||||||
flutter analyze lib --fatal-infos
|
|
||||||
|
|
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/
|
25
README.md
25
README.md
|
@ -33,7 +33,11 @@ Without further delay behold my new Lightmeter app inspired by Material You (a.k
|
||||||
|
|
||||||
To build this app you need to install Flutter 3.10.0 stable. [How to install](https://docs.flutter.dev/get-started/install).
|
To build this app you need to install Flutter 3.10.0 stable. [How to install](https://docs.flutter.dev/get-started/install).
|
||||||
|
|
||||||
### 3. Project setup
|
### 2. (Optional) Install Firebase
|
||||||
|
|
||||||
|
Out of the box Firebase Crashlytics won't work. If you want to add Crashlytics to your local build please follow [this guide](https://firebase.google.com/docs/flutter/setup).
|
||||||
|
|
||||||
|
### 3. Get packages
|
||||||
|
|
||||||
As part of the app's functionallity is in the private repo, you have to replace these lines in _pubspec.yaml_:
|
As part of the app's functionallity is in the private repo, you have to replace these lines in _pubspec.yaml_:
|
||||||
|
|
||||||
|
@ -43,39 +47,24 @@ m3_lightmeter_iap:
|
||||||
url: "https://github.com/vodemn/m3_lightmeter_iap"
|
url: "https://github.com/vodemn/m3_lightmeter_iap"
|
||||||
ref: main
|
ref: main
|
||||||
```
|
```
|
||||||
|
|
||||||
with these:
|
with these:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
m3_lightmeter_iap:
|
m3_lightmeter_iap:
|
||||||
path: iap
|
path: iap
|
||||||
```
|
```
|
||||||
|
and run `flutter pub get` from the _iap/_ folder.
|
||||||
You can do it simply by running the script:
|
|
||||||
|
|
||||||
```console
|
|
||||||
sh .github/scripts/stub_iap.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
> If you are using VSCode, you can open the workspace like so: _File -> Open Workspace from File -> m3_lightmeter.code-workspace_. Otherwise you have to run `flutter pub get` command from the iap folder.
|
|
||||||
|
|
||||||
Then you can fetch all the neccessary dependencies and generate translation files by running the following commands:
|
Then you can fetch all the neccessary dependencies and generate translation files by running the following commands:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
flutter pub get
|
flutter pub get
|
||||||
flutter pub run intl_utils:generate
|
flutter pub run intl_utils:generate
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. (Optional) Install Firebase
|
### 4. Build
|
||||||
|
|
||||||
Out of the box Firebase Crashlytics won't work. If you want to add Crashlytics to your local build please follow [this guide](https://firebase.google.com/docs/flutter/setup).
|
|
||||||
|
|
||||||
### 5. 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 dev --dart-define cameraPreviewAspectRatio=240/320 -t lib/main_dev.dart
|
||||||
```
|
```
|
||||||
|
|
|
@ -8,7 +8,6 @@ import 'package:m3_lightmeter_iap/src/providers/iap_products_provider.dart';
|
||||||
export 'src/data/models/iap_product.dart';
|
export 'src/data/models/iap_product.dart';
|
||||||
|
|
||||||
export 'src/providers/equipment_profile_provider.dart';
|
export 'src/providers/equipment_profile_provider.dart';
|
||||||
export 'src/providers/films_provider.dart';
|
|
||||||
export 'src/providers/iap_products_provider.dart';
|
export 'src/providers/iap_products_provider.dart';
|
||||||
|
|
||||||
class IAPProviders extends StatelessWidget {
|
class IAPProviders extends StatelessWidget {
|
||||||
|
|
|
@ -23,7 +23,6 @@ class FilmsProviderState extends State<FilmsProvider> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Films(
|
return Films(
|
||||||
values: const [Film.other()],
|
values: const [Film.other()],
|
||||||
filmsInUse: const [Film.other()],
|
|
||||||
selected: const Film.other(),
|
selected: const Film.other(),
|
||||||
child: widget.child,
|
child: widget.child,
|
||||||
);
|
);
|
||||||
|
@ -35,28 +34,15 @@ class FilmsProviderState extends State<FilmsProvider> {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Films extends SelectableInheritedModel<Film> {
|
class Films extends SelectableInheritedModel<Film> {
|
||||||
final List<Film> filmsInUse;
|
|
||||||
|
|
||||||
const Films({
|
const Films({
|
||||||
super.key,
|
super.key,
|
||||||
required super.values,
|
required super.values,
|
||||||
required this.filmsInUse,
|
|
||||||
required super.selected,
|
required super.selected,
|
||||||
required super.child,
|
required super.child,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// [Film.other()] + all the custom fields with actual reciprocity formulas
|
|
||||||
static List<Film> of(BuildContext context) {
|
static List<Film> of(BuildContext context) {
|
||||||
return InheritedModel.inheritFrom<Films>(context)!.values;
|
return InheritedModel.inheritFrom<Films>(context, aspect: SelectableAspect.list)!.values;
|
||||||
}
|
|
||||||
|
|
||||||
/// [Film.other()] + films in use selected by user
|
|
||||||
static List<Film> inUseOf<T>(BuildContext context) {
|
|
||||||
return InheritedModel.inheritFrom<Films>(
|
|
||||||
context,
|
|
||||||
aspect: SelectableAspect.list,
|
|
||||||
)!
|
|
||||||
.filmsInUse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Film selectedOf(BuildContext context) {
|
static Film selectedOf(BuildContext context) {
|
||||||
|
|
|
@ -13,6 +13,22 @@ class SelectableInheritedModel<T> extends InheritedModel<SelectableAspect> {
|
||||||
final List<T> values;
|
final List<T> values;
|
||||||
final T selected;
|
final T selected;
|
||||||
|
|
||||||
|
static List<T> of<T>(BuildContext context) {
|
||||||
|
return InheritedModel.inheritFrom<SelectableInheritedModel<T>>(
|
||||||
|
context,
|
||||||
|
aspect: SelectableAspect.list,
|
||||||
|
)!
|
||||||
|
.values;
|
||||||
|
}
|
||||||
|
|
||||||
|
static T selectedOf<T>(BuildContext context) {
|
||||||
|
return InheritedModel.inheritFrom<SelectableInheritedModel>(
|
||||||
|
context,
|
||||||
|
aspect: SelectableAspect.selected,
|
||||||
|
)!
|
||||||
|
.selected;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool updateShouldNotify(SelectableInheritedModel oldWidget) => true;
|
bool updateShouldNotify(SelectableInheritedModel oldWidget) => true;
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
"film": "Film",
|
"film": "Film",
|
||||||
"filmPush": "Film (push)",
|
"filmPush": "Film (push)",
|
||||||
"filmPull": "Film (pull)",
|
"filmPull": "Film (pull)",
|
||||||
"filmReciprocityHint": "Applies correction for shutter speeds grater than 1 second",
|
|
||||||
"equipment": "Equipment",
|
"equipment": "Equipment",
|
||||||
"equipmentProfileName": "Equipment profile name",
|
"equipmentProfileName": "Equipment profile name",
|
||||||
"equipmentProfileNameHint": "Praktica MTL5B",
|
"equipmentProfileNameHint": "Praktica MTL5B",
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
"film": "Pellicule",
|
"film": "Pellicule",
|
||||||
"filmPush": "Pellicule (push)",
|
"filmPush": "Pellicule (push)",
|
||||||
"filmPull": "Pellicule (pull)",
|
"filmPull": "Pellicule (pull)",
|
||||||
"filmReciprocityHint": "La correction s'applique aux vitesses d'obturation supérieures à 1 seconde",
|
|
||||||
"equipment": "Équipement",
|
"equipment": "Équipement",
|
||||||
"equipmentProfileName": "Nom du profil de l'équipement",
|
"equipmentProfileName": "Nom du profil de l'équipement",
|
||||||
"equipmentProfileNameHint": "Praktica MTL5B",
|
"equipmentProfileNameHint": "Praktica MTL5B",
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
"film": "Пленка",
|
"film": "Пленка",
|
||||||
"filmPush": "Пленка (push)",
|
"filmPush": "Пленка (push)",
|
||||||
"filmPull": "Пленка (pull)",
|
"filmPull": "Пленка (pull)",
|
||||||
"filmReciprocityHint": "Применяет коррекцию для выдержек длиннее 1 секунды",
|
|
||||||
"equipment": "Оборудование",
|
"equipment": "Оборудование",
|
||||||
"equipmentProfileName": "Название профиля",
|
"equipmentProfileName": "Название профиля",
|
||||||
"equipmentProfileNameHint": "Praktica MTL5B",
|
"equipmentProfileNameHint": "Praktica MTL5B",
|
||||||
|
@ -93,4 +92,4 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -43,7 +43,6 @@
|
||||||
"film": "胶片",
|
"film": "胶片",
|
||||||
"filmPush": "胶片 (push)",
|
"filmPush": "胶片 (push)",
|
||||||
"filmPull": "胶片 (pull)",
|
"filmPull": "胶片 (pull)",
|
||||||
"filmReciprocityHint": "Applies correction for shutter speeds grater than 1 second",
|
|
||||||
"equipment": "设备",
|
"equipment": "设备",
|
||||||
"equipmentProfileName": "设备配置名称",
|
"equipmentProfileName": "设备配置名称",
|
||||||
"equipmentProfileNameHint": "Praktica MTL5B",
|
"equipmentProfileNameHint": "Praktica MTL5B",
|
||||||
|
|
|
@ -15,9 +15,8 @@ class FilmPicker extends StatelessWidget {
|
||||||
return AnimatedDialogPicker<Film>(
|
return AnimatedDialogPicker<Film>(
|
||||||
icon: Icons.camera_roll,
|
icon: Icons.camera_roll,
|
||||||
title: S.of(context).film,
|
title: S.of(context).film,
|
||||||
subtitle: S.of(context).filmReciprocityHint,
|
|
||||||
selectedValue: Films.selectedOf(context),
|
selectedValue: Films.selectedOf(context),
|
||||||
values: Films.inUseOf(context),
|
values: Films.of(context),
|
||||||
itemTitleBuilder: (_, value) => Text(value.name.isEmpty ? S.of(context).none : value.name),
|
itemTitleBuilder: (_, value) => Text(value.name.isEmpty ? S.of(context).none : value.name),
|
||||||
onChanged: FilmsProvider.of(context).setFilm,
|
onChanged: FilmsProvider.of(context).setFilm,
|
||||||
closedChild: ReadingValueContainer.singleValue(
|
closedChild: ReadingValueContainer.singleValue(
|
||||||
|
|
|
@ -20,8 +20,8 @@ class FilmsListTile extends StatelessWidget {
|
||||||
icon: const Icon(Icons.camera_roll),
|
icon: const Icon(Icons.camera_roll),
|
||||||
title: S.of(context).filmsInUse,
|
title: S.of(context).filmsInUse,
|
||||||
description: S.of(context).filmsInUseDescription,
|
description: S.of(context).filmsInUseDescription,
|
||||||
values: Films.of(context).sublist(1),
|
values: Film.values.sublist(1),
|
||||||
selectedValues: Films.inUseOf(context),
|
selectedValues: Films.of(context),
|
||||||
titleAdapter: (_, value) => value.name,
|
titleAdapter: (_, value) => value.name,
|
||||||
),
|
),
|
||||||
).then((values) {
|
).then((values) {
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
"folders": [
|
|
||||||
{
|
|
||||||
"path": "iap"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"settings": {}
|
|
||||||
}
|
|
Loading…
Reference in a new issue