Compare commits

..

No commits in common. "41431ba0b88116dd442882321ddefbee50ff6a30" and "667cfe2b03502acf03e21cb7b2f1a0ece01113ed" have entirely different histories.

11 changed files with 83 additions and 310 deletions

View file

@ -8,9 +8,6 @@ name: Build prod .aab & .apk
on: on:
workflow_dispatch: workflow_dispatch:
env:
BUILD_ARGS: --release --flavor prod --dart-define cameraPreviewAspectRatio=2/3 -t lib/main_prod.dart
jobs: jobs:
build: build:
runs-on: macos-11 runs-on: macos-11
@ -73,7 +70,7 @@ jobs:
flutter pub run intl_utils:generate flutter pub run intl_utils:generate
- name: Build apk - name: Build apk
run: flutter build apk $BUILD_ARGS run: flutter build apk --release --flavor prod --dart-define cameraPreviewAspectRatio=2/3 -t lib/main_prod.dart
- name: Upload apk to artifacts - name: Upload apk to artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
@ -82,10 +79,23 @@ jobs:
path: build/app/outputs/flutter-apk/app-prod-release.apk path: build/app/outputs/flutter-apk/app-prod-release.apk
- name: Build appbundle - name: Build appbundle
run: flutter build appbundle $BUILD_ARGS run: flutter build appbundle --release --flavor prod --dart-define cameraPreviewAspectRatio=2/3 -t lib/main_prod.dart
- name: Upload app bundle to artifacts - name: Upload app bundle to artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: m3_lightmeter_bundle name: m3_lightmeter_bundle
path: build/app/outputs/bundle/prodRelease/app-prod-release.aab path: build/app/outputs/bundle/prodRelease/app-prod-release.aab
- name: Zip merged_native_libs folder
uses: thedoctor0/zip-release@0.7.1
with:
type: 'zip'
path: 'build/app/intermediates/merged_native_libs/prodRelease/out/lib/'
filename: 'merged_native_libs.zip'
- name: Upload merged_native_libs to artifacts
uses: actions/upload-artifact@v3
with:
name: merged_native_libs
path: merged_native_libs.zip

View file

@ -57,10 +57,7 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 33 targetSdkVersion 33
ndk { ndk.abiFilters 'armeabi-v7a', 'arm64-v8a'
debugSymbolLevel 'FULL'
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
/// legacy material-lightmeter ap stopped updating after 60022 /// legacy material-lightmeter ap stopped updating after 60022
/// 7xxxx means that it is a new app /// 7xxxx means that it is a new app
versionCode 70000 + flutterVersionCode.toInteger() versionCode 70000 + flutterVersionCode.toInteger()
@ -98,10 +95,7 @@ android {
signingConfig signingConfigs.release signingConfig signingConfigs.release
minifyEnabled true minifyEnabled true
shrinkResources true shrinkResources true
ndk { ndk.abiFilters 'armeabi-v7a', 'arm64-v8a'
debugSymbolLevel 'FULL'
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
} }
} }
} }

View file

@ -6,7 +6,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.2.1' classpath 'com.android.tools.build:gradle:7.1.2'
classpath 'com.google.gms:google-services:4.3.10' classpath 'com.google.gms:google-services:4.3.10'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1' classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

View file

@ -9,7 +9,7 @@ class CaffeineService {
return _methodChannel.invokeMethod<bool>("isKeepScreenOn").then((value) => value!); return _methodChannel.invokeMethod<bool>("isKeepScreenOn").then((value) => value!);
} }
Future<bool> keepScreenOn(bool keep) async { Future<void> keepScreenOn(bool keep) async {
return _methodChannel.invokeMethod<bool>("setKeepScreenOn", keep).then((value) => value!); await _methodChannel.invokeMethod<bool>("setKeepScreenOn", keep);
} }
} }

View file

@ -23,8 +23,6 @@ double log10polynomian(
/// do not have any reciprocity failure information, as these films are ment to be used in cinema /// do not have any reciprocity failure information, as these films are ment to be used in cinema
/// with appropriate light and pretty short shutter speeds. /// with appropriate light and pretty short shutter speeds.
/// ///
/// Because of this: https://github.com/dart-lang/sdk/issues/38934#issuecomment-803938315
/// `super` calls are ignored in test coverage
class Film { class Film {
final String name; final String name;
final int iso; final int iso;
@ -80,26 +78,26 @@ class Film {
/// https://www.tate.org.uk/documents/598/page_6_7_agfa_stocks_0.pdf /// https://www.tate.org.uk/documents/598/page_6_7_agfa_stocks_0.pdf
/// https://www.filmwasters.com/forum/index.php?topic=5298.0 /// https://www.filmwasters.com/forum/index.php?topic=5298.0
// {{1,1.87},{2,3.73},{3,8.06},{4,13.93},{5,21.28},{6,23.00},{7,30.12},{8,38.05},{9,44.75},{10,50.12},{20,117},{30,202},{40,293},{50,413},{60,547},{70,694},{80,853},{90,1022},{100,1202}}; // {{1,1.87},{2,3.73},{3,8.06},{4,13.93},{5,21.28},{6,23.00},{7,30.12},{8,38.05},{9,44.75},{10,50.12},{20,117},{30,202},{40,293},{50,413},{60,547},{70,694},{80,853},{90,1022},{100,1202}};
// class AgfaFilm extends Film { class AgfaFilm extends Film {
// final double a; final double a;
// final double b; final double b;
// final double c; final double c;
// const AgfaFilm.apx100() const AgfaFilm.apx100()
// : a = 1, : a = 1,
// b = 5, b = 5,
// c = 2, c = 2,
// super('Agfa APX 100', 100); // coverage:ignore-line super('Agfa APX 100', 100);
// const AgfaFilm.apx400() const AgfaFilm.apx400()
// : a = 1.5, : a = 1.5,
// b = 4.5, b = 4.5,
// c = 3, c = 3,
// super('Agfa APX 400', 400); // coverage:ignore-line super('Agfa APX 400', 400);
// @override @override
// double reciprocityFormula(double t) => t * log10polynomian(t, a, b, c); double reciprocityFormula(double t) => t * log10polynomian(t, a, b, c);
// } }
class FomapanFilm extends Film { class FomapanFilm extends Film {
final double a; final double a;
@ -111,21 +109,21 @@ class FomapanFilm extends Film {
: a = 1, : a = 1,
b = 5, b = 5,
c = 2, c = 2,
super('Fomapan CREATIVE 100', 100); // coverage:ignore-line super('Fomapan CREATIVE 100', 100);
/// https://www.foma.cz/en/fomapan-200 /// https://www.foma.cz/en/fomapan-200
const FomapanFilm.creative200() const FomapanFilm.creative200()
: a = 1.5, : a = 1.5,
b = 4.5, b = 4.5,
c = 3, c = 3,
super('Fomapan CREATIVE 200', 200); // coverage:ignore-line super('Fomapan CREATIVE 200', 200);
/// https://www.foma.cz/en/fomapan-100 /// https://www.foma.cz/en/fomapan-100
const FomapanFilm.action400() const FomapanFilm.action400()
: a = -1.25, // coverage:ignore-line : a = -1.25,
b = 5.75, b = 5.75,
c = 1.5, c = 1.5,
super('Fomapan ACTION 400', 400); // coverage:ignore-line super('Fomapan ACTION 400', 400);
@override @override
double reciprocityFormula(double t) => t * log10polynomian(t, a, b, c); double reciprocityFormula(double t) => t * log10polynomian(t, a, b, c);
@ -137,57 +135,57 @@ class IlfordFilm extends Film {
/// https://www.ilfordphoto.com/amfile/file/download/file/1948/product/1650/ /// https://www.ilfordphoto.com/amfile/file/download/file/1948/product/1650/
const IlfordFilm.ortho() const IlfordFilm.ortho()
: reciprocityPower = 1.25, : reciprocityPower = 1.25,
super('Ilford ORTHO+', 80); // coverage:ignore-line super('Ilford ORTHO+', 80);
/// https://www.ilfordphoto.com/amfile/file/download/file/1919/product/686/ /// https://www.ilfordphoto.com/amfile/file/download/file/1919/product/686/
const IlfordFilm.fp4() const IlfordFilm.fp4()
: reciprocityPower = 1.26, : reciprocityPower = 1.26,
super('Ilford FP4+', 125); // coverage:ignore-line super('Ilford FP4+', 125);
/// https://www.ilfordphoto.com/amfile/file/download/file/1903/product/691/ /// https://www.ilfordphoto.com/amfile/file/download/file/1903/product/691/
const IlfordFilm.hp5() const IlfordFilm.hp5()
: reciprocityPower = 1.31, : reciprocityPower = 1.31,
super('Ilford HP5+', 400); // coverage:ignore-line super('Ilford HP5+', 400);
/// https://www.ilfordphoto.com/amfile/file/download/file/3/product/679/ /// https://www.ilfordphoto.com/amfile/file/download/file/3/product/679/
const IlfordFilm.delta100() const IlfordFilm.delta100()
: reciprocityPower = 1.26, : reciprocityPower = 1.26,
super('Ilford DELTA 100', 100); // coverage:ignore-line super('Ilford DELTA 100', 100);
/// https://www.ilfordphoto.com/amfile/file/download/file/1915/product/684/ /// https://www.ilfordphoto.com/amfile/file/download/file/1915/product/684/
const IlfordFilm.delta400() const IlfordFilm.delta400()
: reciprocityPower = 1.41, : reciprocityPower = 1.41,
super('Ilford DELTA 400', 400); // coverage:ignore-line super('Ilford DELTA 400', 400);
/// https://www.ilfordphoto.com/amfile/file/download/file/1913/product/682/ /// https://www.ilfordphoto.com/amfile/file/download/file/1913/product/682/
const IlfordFilm.delta3200() const IlfordFilm.delta3200()
: reciprocityPower = 1.33, : reciprocityPower = 1.33,
super('Ilford DELTA 3200', 3200); // coverage:ignore-line super('Ilford DELTA 3200', 3200);
/// https://www.ilfordphoto.com/amfile/file/download/file/1905/product/699/ /// https://www.ilfordphoto.com/amfile/file/download/file/1905/product/699/
const IlfordFilm.panf() const IlfordFilm.panf()
: reciprocityPower = 1.33, : reciprocityPower = 1.33,
super('Ilford Pan F+', 50); // coverage:ignore-line super('Ilford Pan F+', 50);
/// https://www.ilfordphoto.com/amfile/file/download/file/1907/product/701/ /// https://www.ilfordphoto.com/amfile/file/download/file/1907/product/701/
const IlfordFilm.sfx200() const IlfordFilm.sfx200()
: reciprocityPower = 1.31, : reciprocityPower = 1.31,
super('Ilford SFX 200', 200); // coverage:ignore-line super('Ilford SFX 200', 200);
/// https://www.ilfordphoto.com/amfile/file/download/file/1909/product/703/ /// https://www.ilfordphoto.com/amfile/file/download/file/1909/product/703/
const IlfordFilm.xp2super() const IlfordFilm.xp2super()
: reciprocityPower = 1.31, : reciprocityPower = 1.31,
super('Ilford XP2 SUPER', 400); // coverage:ignore-line super('Ilford XP2 SUPER', 400);
/// https://www.ilfordphoto.com/amfile/file/download/file/1958/product/696/ /// https://www.ilfordphoto.com/amfile/file/download/file/1958/product/696/
const IlfordFilm.pan100() const IlfordFilm.pan100()
: reciprocityPower = 1.26, : reciprocityPower = 1.26,
super('Kentemere 100', 100); // coverage:ignore-line super('Kentemere 100', 100);
/// https://www.ilfordphoto.com/amfile/file/download/file/1959/product/697/ /// https://www.ilfordphoto.com/amfile/file/download/file/1959/product/697/
const IlfordFilm.pan400() const IlfordFilm.pan400()
: reciprocityPower = 1.30, : reciprocityPower = 1.30,
super('Kentemere 400', 400); // coverage:ignore-line super('Kentemere 400', 400);
@override @override
double reciprocityFormula(double t) => pow(t, reciprocityPower).toDouble(); double reciprocityFormula(double t) => pow(t, reciprocityPower).toDouble();
@ -199,34 +197,34 @@ class KodakFilm extends Film {
final double c; final double c;
const KodakFilm.tmax100() const KodakFilm.tmax100()
: a = 1 / 6, // coverage:ignore-line : a = 1 / 6,
b = 0, // coverage:ignore-line b = 0,
c = 4 / 3, // coverage:ignore-line c = 4 / 3,
super('Kodak T-MAX 100', 100); // coverage:ignore-line super('Kodak T-MAX 100', 100);
const KodakFilm.tmax400() const KodakFilm.tmax400()
: a = 2 / 3, // coverage:ignore-line : a = 2 / 3,
b = -1 / 2, // coverage:ignore-line b = -1 / 2,
c = 4 / 3, // coverage:ignore-line c = 4 / 3,
super('Kodak T-MAX 400', 400); // coverage:ignore-line super('Kodak T-MAX 400', 400);
const KodakFilm.tmax3200() const KodakFilm.tmax3200()
: a = 7 / 6, // coverage:ignore-line : a = 7 / 6,
b = -1, // coverage:ignore-line b = -1,
c = 4 / 3, // coverage:ignore-line c = 4 / 3,
super('Kodak T-MAX 3200', 3200); // coverage:ignore-line super('Kodak T-MAX 3200', 3200);
const KodakFilm.trix320() const KodakFilm.trix320()
: a = 2, : a = 2,
b = 1, b = 1,
c = 2, c = 2,
super('Kodak TRI-X 320', 320); // coverage:ignore-line super('Kodak TRI-X 320', 320);
const KodakFilm.trix400() const KodakFilm.trix400()
: a = 2, : a = 2,
b = 1, b = 1,
c = 2, c = 2,
super('Kodak TRI-X 400', 400); // coverage:ignore-line super('Kodak TRI-X 400', 400);
@override @override
double reciprocityFormula(double t) => t * log10polynomian(t, a, b, c); double reciprocityFormula(double t) => t * log10polynomian(t, a, b, c);

View file

@ -1,5 +1,20 @@
import 'package:intl/intl.dart';
enum SupportedLocale { en, fr, ru } enum SupportedLocale { en, fr, ru }
SupportedLocale get currentLanguage {
switch (Intl.getCurrentLocale()) {
case "en":
return SupportedLocale.en;
case "fr":
return SupportedLocale.fr;
case "ru":
return SupportedLocale.ru;
default:
return SupportedLocale.en;
}
}
extension SupportedLocaleExtension on SupportedLocale { extension SupportedLocaleExtension on SupportedLocale {
String get intlName => toString().replaceAll("SupportedLocale.", ""); String get intlName => toString().replaceAll("SupportedLocale.", "");

View file

@ -1,7 +1,7 @@
name: lightmeter name: lightmeter
description: A new Flutter project. description: A new Flutter project.
publish_to: "none" publish_to: "none"
version: 0.11.5+28 version: 0.11.4+27
environment: environment:
sdk: ">=3.0.0 <4.0.0" sdk: ">=3.0.0 <4.0.0"

View file

@ -1,76 +0,0 @@
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:lightmeter/data/caffeine_service.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
late CaffeineService service;
const methodChannel = MethodChannel('com.vodemn.lightmeter/keepScreenOn');
Future<Object?>? cameraMethodCallSuccessHandler(MethodCall methodCall) async {
switch (methodCall.method) {
case "isKeepScreenOn":
return true;
case "setKeepScreenOn":
return methodCall.arguments as bool;
default:
return null;
}
}
setUp(() {
service = const CaffeineService();
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(methodChannel, cameraMethodCallSuccessHandler);
});
tearDown(() {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(methodChannel, null);
});
group(
'isKeepScreenOn()',
() {
test('true', () async {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(methodChannel, null);
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(methodChannel, (methodCall) async {
switch (methodCall.method) {
case "isKeepScreenOn":
return true;
default:
return null;
}
});
expectLater(service.isKeepScreenOn(), completion(true));
});
test('false', () async {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(methodChannel, null);
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(methodChannel, (methodCall) async {
switch (methodCall.method) {
case "isKeepScreenOn":
return false;
default:
return null;
}
});
expectLater(service.isKeepScreenOn(), completion(false));
});
},
);
group(
'keepScreenOn()',
() {
test('true', () async => expectLater(service.keepScreenOn(true), completion(true)));
test('false', () async => expectLater(service.keepScreenOn(false), completion(false)));
},
);
}

View file

@ -1,121 +0,0 @@
import 'package:lightmeter/data/models/film.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
import 'package:test/test.dart';
void main() {
test('iso', () {
expect(const Film.other().iso, 0);
expect(const FomapanFilm.creative100().iso, 100);
expect(const FomapanFilm.creative200().iso, 200);
expect(const FomapanFilm.action400().iso, 400);
expect(const IlfordFilm.ortho().iso, 80);
expect(const IlfordFilm.delta100().iso, 100);
expect(const IlfordFilm.delta400().iso, 400);
expect(const IlfordFilm.delta3200().iso, 3200);
expect(const IlfordFilm.fp4().iso, 125);
expect(const IlfordFilm.hp5().iso, 400);
expect(const IlfordFilm.panf().iso, 50);
expect(const IlfordFilm.sfx200().iso, 200);
expect(const IlfordFilm.xp2super().iso, 400);
expect(const IlfordFilm.pan100().iso, 100);
expect(const IlfordFilm.pan400().iso, 400);
expect(const KodakFilm.tmax100().iso, 100);
expect(const KodakFilm.tmax400().iso, 400);
expect(const KodakFilm.tmax3200().iso, 3200);
expect(const KodakFilm.trix320().iso, 320);
expect(const KodakFilm.trix400().iso, 400);
});
test('toString()', () {
expect(const Film.other().toString(), "");
expect(const FomapanFilm.creative100().toString(), "Fomapan CREATIVE 100");
expect(const FomapanFilm.creative200().toString(), "Fomapan CREATIVE 200");
expect(const FomapanFilm.action400().toString(), "Fomapan ACTION 400");
expect(const IlfordFilm.ortho().toString(), "Ilford ORTHO+");
expect(const IlfordFilm.delta100().toString(), "Ilford DELTA 100");
expect(const IlfordFilm.delta400().toString(), "Ilford DELTA 400");
expect(const IlfordFilm.delta3200().toString(), "Ilford DELTA 3200");
expect(const IlfordFilm.fp4().toString(), "Ilford FP4+");
expect(const IlfordFilm.hp5().toString(), "Ilford HP5+");
expect(const IlfordFilm.panf().toString(), "Ilford Pan F+");
expect(const IlfordFilm.sfx200().toString(), "Ilford SFX 200");
expect(const IlfordFilm.xp2super().toString(), "Ilford XP2 SUPER");
expect(const IlfordFilm.pan100().toString(), "Kentemere 100");
expect(const IlfordFilm.pan400().toString(), "Kentemere 400");
expect(const KodakFilm.tmax100().toString(), "Kodak T-MAX 100");
expect(const KodakFilm.tmax400().toString(), "Kodak T-MAX 400");
expect(const KodakFilm.tmax3200().toString(), "Kodak T-MAX 3200");
expect(const KodakFilm.trix320().toString(), "Kodak TRI-X 320");
expect(const KodakFilm.trix400().toString(), "Kodak TRI-X 400");
});
group(
'reciprocityFailure',
() {
const inputSpeeds = [
ShutterSpeedValue(1000, true, StopType.full),
ShutterSpeedValue(1, false, StopType.full),
ShutterSpeedValue(16, false, StopType.full)
];
test('No change `Film.other()`', () {
expect(
const Film.other().reciprocityFailure(inputSpeeds[0]),
const ShutterSpeedValue(1000, true, StopType.full),
);
expect(
const Film.other().reciprocityFailure(inputSpeeds[1]),
const ShutterSpeedValue(1, false, StopType.full),
);
expect(
const Film.other().reciprocityFailure(inputSpeeds[2]),
const ShutterSpeedValue(16, false, StopType.full),
);
});
test('pow `IlfordFilm.delta100()`', () {
expect(
const IlfordFilm.delta100().reciprocityFailure(inputSpeeds[0]),
const ShutterSpeedValue(1000, true, StopType.full),
);
expect(
const IlfordFilm.delta100().reciprocityFailure(inputSpeeds[1]),
const ShutterSpeedValue(1, false, StopType.full),
);
expect(
const IlfordFilm.delta100().reciprocityFailure(inputSpeeds[2]),
const ShutterSpeedValue(32.899642452994128, false, StopType.full),
);
});
test('log10polynomian `FomapanFilm.creative100()`', () {
expect(
const FomapanFilm.creative100().reciprocityFailure(inputSpeeds[0]),
const ShutterSpeedValue(1000, true, StopType.full),
);
expect(
const FomapanFilm.creative100().reciprocityFailure(inputSpeeds[1]),
const ShutterSpeedValue(2, false, StopType.full),
);
expect(
const FomapanFilm.creative100().reciprocityFailure(inputSpeeds[2]),
const ShutterSpeedValue(151.52807753457483, false, StopType.full),
);
});
test('log10polynomian `Kodak.tmax400()`', () {
expect(
const KodakFilm.tmax400().reciprocityFailure(inputSpeeds[0]),
const ShutterSpeedValue(1000, true, StopType.full),
);
expect(
const KodakFilm.tmax400().reciprocityFailure(inputSpeeds[1]),
const ShutterSpeedValue(1.3333333333333333, false, StopType.full),
);
expect(
const KodakFilm.tmax400().reciprocityFailure(inputSpeeds[2]),
const ShutterSpeedValue(27.166026086819844, false, StopType.full),
);
});
},
);
}

View file

@ -1,31 +0,0 @@
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
import 'package:test/test.dart';
void main() {
test('fromJson', () {
expect(
MeteringScreenLayoutConfigJson.fromJson({'0': true, '1': true}),
{
MeteringScreenLayoutFeature.extremeExposurePairs: true,
MeteringScreenLayoutFeature.filmPicker: true,
},
);
expect(
MeteringScreenLayoutConfigJson.fromJson({'0': false, '1': false}),
{
MeteringScreenLayoutFeature.extremeExposurePairs: false,
MeteringScreenLayoutFeature.filmPicker: false,
},
);
});
test('toJson', () {
expect(
{
MeteringScreenLayoutFeature.extremeExposurePairs: true,
MeteringScreenLayoutFeature.filmPicker: true,
}.toJson(),
{'0': true, '1': true},
);
});
}

View file

@ -1,16 +0,0 @@
import 'package:lightmeter/data/models/supported_locale.dart';
import 'package:test/test.dart';
void main() {
test('intlName', () {
expect(SupportedLocale.en.intlName, 'en');
expect(SupportedLocale.fr.intlName, 'fr');
expect(SupportedLocale.ru.intlName, 'ru');
});
test('localizedName', () {
expect(SupportedLocale.en.localizedName, 'English');
expect(SupportedLocale.fr.localizedName, 'Français');
expect(SupportedLocale.ru.localizedName, 'Русский');
});
}