mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-24 08:20:40 +00:00
Compare commits
No commits in common. "67818f7c8c2fb97e9cd706375a6f01df7af61bfd" and "92297c99ef8c559e44d313cd140976b1dcf6f92b" have entirely different histories.
67818f7c8c
...
92297c99ef
15 changed files with 128 additions and 853 deletions
15
.github/workflows/cd_prod.yml
vendored
15
.github/workflows/cd_prod.yml
vendored
|
@ -101,7 +101,7 @@ jobs:
|
||||||
update-version-in-repo:
|
update-version-in-repo:
|
||||||
name: Update repo version
|
name: Update repo version
|
||||||
needs: [build]
|
needs: [build]
|
||||||
runs-on: ubuntu-latest
|
runs-on: macos-11
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
|
@ -109,20 +109,15 @@ jobs:
|
||||||
|
|
||||||
- name: Increment build number & replace version number
|
- name: Increment build number & replace version number
|
||||||
run: perl -i -pe 's/^(version:\s+)(\d+\.\d+\.\d+)(\+)(\d+)$/$1."${{ github.event.inputs.version }}".$3.($4+1)/e' pubspec.yaml
|
run: perl -i -pe 's/^(version:\s+)(\d+\.\d+\.\d+)(\+)(\d+)$/$1."${{ github.event.inputs.version }}".$3.($4+1)/e' pubspec.yaml
|
||||||
|
|
||||||
- name: Commit changes
|
- name: Commit and push changes
|
||||||
run: |
|
run: |
|
||||||
git config --global user.name "vodemn"
|
git config --global user.name "vodemn"
|
||||||
git config --global user.email "vadim.turko@gmail.com"
|
git config --global user.email "vadim.turko@gmail.com"
|
||||||
|
|
||||||
git add -A
|
git add -A
|
||||||
git commit -m "Version bump"
|
git commit -m "Version bump"
|
||||||
|
git push
|
||||||
- name: Push to main
|
|
||||||
uses: CasperWA/push-protected@v2
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.PUSH_TO_MAIN_TOKEN }}
|
|
||||||
branch: main
|
|
||||||
unprotect_reviews: true
|
|
||||||
|
|
||||||
create-release:
|
create-release:
|
||||||
name: Create Github release
|
name: Create Github release
|
||||||
|
|
|
@ -33,6 +33,10 @@ apply plugin: 'com.google.firebase.crashlytics'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||||
|
|
||||||
|
gradle.beforeProject({ project->
|
||||||
|
project.setProperty("target-platform", "android-arm,android-arm64")
|
||||||
|
})
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 33
|
compileSdkVersion 33
|
||||||
ndkVersion flutter.ndkVersion
|
ndkVersion flutter.ndkVersion
|
||||||
|
@ -108,5 +112,5 @@ flutter {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
implementation "com.android.billingclient:billing-ktx:6.0.0"
|
implementation "com.android.billingclient:billing-ktx:5.1.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@ buildscript {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.4.2'
|
classpath 'com.android.tools.build:gradle:7.2.1'
|
||||||
classpath 'com.google.gms:google-services:4.3.15'
|
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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.", "");
|
||||||
|
|
||||||
|
|
|
@ -10,32 +10,30 @@ import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
class UserPreferencesService {
|
class UserPreferencesService {
|
||||||
static const isoKey = "iso";
|
static const _isoKey = "iso";
|
||||||
static const ndFilterKey = "ndFilter";
|
static const _ndFilterKey = "ndFilter";
|
||||||
|
|
||||||
static const evSourceTypeKey = "evSourceType";
|
static const _evSourceTypeKey = "evSourceType";
|
||||||
static const stopTypeKey = "stopType";
|
static const _cameraEvCalibrationKey = "cameraEvCalibration";
|
||||||
static const cameraEvCalibrationKey = "cameraEvCalibration";
|
static const _lightSensorEvCalibrationKey = "lightSensorEvCalibration";
|
||||||
static const lightSensorEvCalibrationKey = "lightSensorEvCalibration";
|
static const _meteringScreenLayoutKey = "meteringScreenLayout";
|
||||||
static const meteringScreenLayoutKey = "meteringScreenLayout";
|
static const _filmKey = "film";
|
||||||
static const filmKey = "film";
|
|
||||||
|
|
||||||
static const caffeineKey = "caffeine";
|
static const _caffeineKey = "caffeine";
|
||||||
static const hapticsKey = "haptics";
|
static const _hapticsKey = "haptics";
|
||||||
static const localeKey = "locale";
|
static const _localeKey = "locale";
|
||||||
|
|
||||||
static const themeTypeKey = "themeType";
|
static const _themeTypeKey = "themeType";
|
||||||
static const primaryColorKey = "primaryColor";
|
static const _primaryColorKey = "primaryColor";
|
||||||
static const dynamicColorKey = "dynamicColor";
|
static const _dynamicColorKey = "dynamicColor";
|
||||||
|
|
||||||
final SharedPreferences _sharedPreferences;
|
final SharedPreferences _sharedPreferences;
|
||||||
|
|
||||||
UserPreferencesService(this._sharedPreferences) {
|
UserPreferencesService(this._sharedPreferences) {
|
||||||
migrateOldKeys();
|
_migrateOldKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
@visibleForTesting
|
Future<void> _migrateOldKeys() async {
|
||||||
Future<void> migrateOldKeys() async {
|
|
||||||
final legacyIsoIndex = _sharedPreferences.getInt("curIsoIndex");
|
final legacyIsoIndex = _sharedPreferences.getInt("curIsoIndex");
|
||||||
if (legacyIsoIndex != null) {
|
if (legacyIsoIndex != null) {
|
||||||
iso = IsoValue.values[legacyIsoIndex];
|
iso = IsoValue.values[legacyIsoIndex];
|
||||||
|
@ -71,25 +69,22 @@ class UserPreferencesService {
|
||||||
}
|
}
|
||||||
|
|
||||||
IsoValue get iso =>
|
IsoValue get iso =>
|
||||||
IsoValue.values.firstWhere((v) => v.value == (_sharedPreferences.getInt(isoKey) ?? 100));
|
IsoValue.values.firstWhere((v) => v.value == (_sharedPreferences.getInt(_isoKey) ?? 100));
|
||||||
set iso(IsoValue value) => _sharedPreferences.setInt(isoKey, value.value);
|
set iso(IsoValue value) => _sharedPreferences.setInt(_isoKey, value.value);
|
||||||
|
|
||||||
NdValue get ndFilter =>
|
NdValue get ndFilter =>
|
||||||
NdValue.values.firstWhere((v) => v.value == (_sharedPreferences.getInt(ndFilterKey) ?? 0));
|
NdValue.values.firstWhere((v) => v.value == (_sharedPreferences.getInt(_ndFilterKey) ?? 0));
|
||||||
set ndFilter(NdValue value) => _sharedPreferences.setInt(ndFilterKey, value.value);
|
set ndFilter(NdValue value) => _sharedPreferences.setInt(_ndFilterKey, value.value);
|
||||||
|
|
||||||
EvSourceType get evSourceType =>
|
EvSourceType get evSourceType =>
|
||||||
EvSourceType.values[_sharedPreferences.getInt(evSourceTypeKey) ?? 0];
|
EvSourceType.values[_sharedPreferences.getInt(_evSourceTypeKey) ?? 0];
|
||||||
set evSourceType(EvSourceType value) => _sharedPreferences.setInt(evSourceTypeKey, value.index);
|
set evSourceType(EvSourceType value) => _sharedPreferences.setInt(_evSourceTypeKey, value.index);
|
||||||
|
|
||||||
bool get caffeine => _sharedPreferences.getBool(caffeineKey) ?? false;
|
bool get caffeine => _sharedPreferences.getBool(_caffeineKey) ?? false;
|
||||||
set caffeine(bool value) => _sharedPreferences.setBool(caffeineKey, value);
|
set caffeine(bool value) => _sharedPreferences.setBool(_caffeineKey, value);
|
||||||
|
|
||||||
StopType get stopType => StopType.values[_sharedPreferences.getInt(stopTypeKey) ?? 2];
|
|
||||||
set stopType(StopType value) => _sharedPreferences.setInt(stopTypeKey, value.index);
|
|
||||||
|
|
||||||
MeteringScreenLayoutConfig get meteringScreenLayout {
|
MeteringScreenLayoutConfig get meteringScreenLayout {
|
||||||
final configJson = _sharedPreferences.getString(meteringScreenLayoutKey);
|
final configJson = _sharedPreferences.getString(_meteringScreenLayoutKey);
|
||||||
if (configJson != null) {
|
if (configJson != null) {
|
||||||
return MeteringScreenLayoutConfigJson.fromJson(
|
return MeteringScreenLayoutConfigJson.fromJson(
|
||||||
json.decode(configJson) as Map<String, dynamic>,
|
json.decode(configJson) as Map<String, dynamic>,
|
||||||
|
@ -103,44 +98,44 @@ class UserPreferencesService {
|
||||||
}
|
}
|
||||||
|
|
||||||
set meteringScreenLayout(MeteringScreenLayoutConfig value) =>
|
set meteringScreenLayout(MeteringScreenLayoutConfig value) =>
|
||||||
_sharedPreferences.setString(meteringScreenLayoutKey, json.encode(value.toJson()));
|
_sharedPreferences.setString(_meteringScreenLayoutKey, json.encode(value.toJson()));
|
||||||
|
|
||||||
bool get haptics => _sharedPreferences.getBool(hapticsKey) ?? true;
|
bool get haptics => _sharedPreferences.getBool(_hapticsKey) ?? true;
|
||||||
set haptics(bool value) => _sharedPreferences.setBool(hapticsKey, value);
|
set haptics(bool value) => _sharedPreferences.setBool(_hapticsKey, value);
|
||||||
|
|
||||||
SupportedLocale get locale => SupportedLocale.values.firstWhere(
|
SupportedLocale get locale => SupportedLocale.values.firstWhere(
|
||||||
(e) => e.toString() == _sharedPreferences.getString(localeKey),
|
(e) => e.toString() == _sharedPreferences.getString(_localeKey),
|
||||||
orElse: () => SupportedLocale.en,
|
orElse: () => SupportedLocale.en,
|
||||||
);
|
);
|
||||||
set locale(SupportedLocale value) => _sharedPreferences.setString(localeKey, value.toString());
|
set locale(SupportedLocale value) => _sharedPreferences.setString(_localeKey, value.toString());
|
||||||
|
|
||||||
double get cameraEvCalibration => _sharedPreferences.getDouble(cameraEvCalibrationKey) ?? 0.0;
|
double get cameraEvCalibration => _sharedPreferences.getDouble(_cameraEvCalibrationKey) ?? 0.0;
|
||||||
set cameraEvCalibration(double value) =>
|
set cameraEvCalibration(double value) =>
|
||||||
_sharedPreferences.setDouble(cameraEvCalibrationKey, value);
|
_sharedPreferences.setDouble(_cameraEvCalibrationKey, value);
|
||||||
|
|
||||||
double get lightSensorEvCalibration =>
|
double get lightSensorEvCalibration =>
|
||||||
_sharedPreferences.getDouble(lightSensorEvCalibrationKey) ?? 0.0;
|
_sharedPreferences.getDouble(_lightSensorEvCalibrationKey) ?? 0.0;
|
||||||
set lightSensorEvCalibration(double value) =>
|
set lightSensorEvCalibration(double value) =>
|
||||||
_sharedPreferences.setDouble(lightSensorEvCalibrationKey, value);
|
_sharedPreferences.setDouble(_lightSensorEvCalibrationKey, value);
|
||||||
|
|
||||||
ThemeType get themeType => ThemeType.values[_sharedPreferences.getInt(themeTypeKey) ?? 0];
|
ThemeType get themeType => ThemeType.values[_sharedPreferences.getInt(_themeTypeKey) ?? 0];
|
||||||
set themeType(ThemeType value) => _sharedPreferences.setInt(themeTypeKey, value.index);
|
set themeType(ThemeType value) => _sharedPreferences.setInt(_themeTypeKey, value.index);
|
||||||
|
|
||||||
Color get primaryColor => Color(_sharedPreferences.getInt(primaryColorKey) ?? 0xff2196f3);
|
Color get primaryColor => Color(_sharedPreferences.getInt(_primaryColorKey) ?? 0xff2196f3);
|
||||||
set primaryColor(Color value) => _sharedPreferences.setInt(primaryColorKey, value.value);
|
set primaryColor(Color value) => _sharedPreferences.setInt(_primaryColorKey, value.value);
|
||||||
|
|
||||||
bool get dynamicColor => _sharedPreferences.getBool(dynamicColorKey) ?? false;
|
bool get dynamicColor => _sharedPreferences.getBool(_dynamicColorKey) ?? false;
|
||||||
set dynamicColor(bool value) => _sharedPreferences.setBool(dynamicColorKey, value);
|
set dynamicColor(bool value) => _sharedPreferences.setBool(_dynamicColorKey, value);
|
||||||
|
|
||||||
Film get film => Film.values.firstWhere(
|
Film get film => Film.values.firstWhere(
|
||||||
(e) => e.name == _sharedPreferences.getString(filmKey),
|
(e) => e.name == _sharedPreferences.getString(_filmKey),
|
||||||
orElse: () => Film.values.first,
|
orElse: () => Film.values.first,
|
||||||
);
|
);
|
||||||
set film(Film value) => _sharedPreferences.setString(filmKey, value.name);
|
set film(Film value) => _sharedPreferences.setString(_filmKey, value.name);
|
||||||
|
|
||||||
String get selectedEquipmentProfileId => ''; // coverage:ignore-line
|
String get selectedEquipmentProfileId => '';
|
||||||
set selectedEquipmentProfileId(String id) {} // coverage:ignore-line
|
set selectedEquipmentProfileId(String id) {}
|
||||||
|
|
||||||
List<EquipmentProfileData> get equipmentProfiles => []; // coverage:ignore-line
|
List<EquipmentProfileData> get equipmentProfiles => [];
|
||||||
set equipmentProfiles(List<EquipmentProfileData> profiles) {} // coverage:ignore-line
|
set equipmentProfiles(List<EquipmentProfileData> profiles) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:lightmeter/data/shared_prefs_service.dart';
|
|
||||||
import 'package:lightmeter/utils/inherited_generics.dart';
|
import 'package:lightmeter/utils/inherited_generics.dart';
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
|
@ -17,12 +16,14 @@ class StopTypeProvider extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class StopTypeProviderState extends State<StopTypeProvider> {
|
class StopTypeProviderState extends State<StopTypeProvider> {
|
||||||
late StopType _stopType;
|
StopType _stopType = StopType.third;
|
||||||
|
|
||||||
@override
|
StopType get stopType => _stopType;
|
||||||
void initState() {
|
|
||||||
super.initState();
|
void set(StopType type) {
|
||||||
_stopType = context.get<UserPreferencesService>().stopType;
|
setState(() {
|
||||||
|
_stopType = type;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -32,11 +33,4 @@ class StopTypeProviderState extends State<StopTypeProvider> {
|
||||||
child: widget.child,
|
child: widget.child,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(StopType type) {
|
|
||||||
setState(() {
|
|
||||||
_stopType = type;
|
|
||||||
});
|
|
||||||
context.get<UserPreferencesService>().stopType = type;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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?>? methodCallSuccessHandler(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, methodCallSuccessHandler);
|
|
||||||
});
|
|
||||||
|
|
||||||
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)));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:lightmeter/data/light_sensor_service.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
|
||||||
|
|
||||||
late LightSensorService service;
|
|
||||||
|
|
||||||
const methodChannel = MethodChannel('system_feature');
|
|
||||||
// TODO: add event channel mock
|
|
||||||
//const eventChannel = EventChannel('light.eventChannel');
|
|
||||||
|
|
||||||
setUp(() {
|
|
||||||
service = const LightSensorService();
|
|
||||||
});
|
|
||||||
|
|
||||||
tearDown(() {
|
|
||||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
||||||
.setMockMethodCallHandler(methodChannel, null);
|
|
||||||
});
|
|
||||||
|
|
||||||
group(
|
|
||||||
'hasSensor()',
|
|
||||||
() {
|
|
||||||
test('true', () async {
|
|
||||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
||||||
.setMockMethodCallHandler(methodChannel, null);
|
|
||||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
||||||
.setMockMethodCallHandler(methodChannel, (methodCall) async {
|
|
||||||
switch (methodCall.method) {
|
|
||||||
case "sensor":
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
expectLater(service.hasSensor(), completion(true));
|
|
||||||
});
|
|
||||||
|
|
||||||
test('false', () async {
|
|
||||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
||||||
.setMockMethodCallHandler(methodChannel, null);
|
|
||||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
||||||
.setMockMethodCallHandler(methodChannel, (methodCall) async {
|
|
||||||
switch (methodCall.method) {
|
|
||||||
case "sensor":
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
expectLater(service.hasSensor(), completion(false));
|
|
||||||
});
|
|
||||||
test('null', () async {
|
|
||||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
||||||
.setMockMethodCallHandler(methodChannel, null);
|
|
||||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
||||||
.setMockMethodCallHandler(methodChannel, (methodCall) async {
|
|
||||||
switch (methodCall.method) {
|
|
||||||
case "sensor":
|
|
||||||
return null;
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
expectLater(service.hasSensor(), completion(false));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -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),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -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},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -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, 'Русский');
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,411 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:lightmeter/data/models/ev_source_type.dart';
|
|
||||||
import 'package:lightmeter/data/models/film.dart';
|
|
||||||
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
|
|
||||||
import 'package:lightmeter/data/models/supported_locale.dart';
|
|
||||||
import 'package:lightmeter/data/models/theme_type.dart';
|
|
||||||
import 'package:lightmeter/data/shared_prefs_service.dart';
|
|
||||||
import 'package:lightmeter/providers/theme_provider.dart';
|
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
|
||||||
import 'package:mocktail/mocktail.dart';
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
|
|
||||||
class _MockSharedPreferences extends Mock implements SharedPreferences {}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
late _MockSharedPreferences sharedPreferences;
|
|
||||||
late UserPreferencesService service;
|
|
||||||
|
|
||||||
setUpAll(() {
|
|
||||||
sharedPreferences = _MockSharedPreferences();
|
|
||||||
service = UserPreferencesService(sharedPreferences);
|
|
||||||
});
|
|
||||||
|
|
||||||
tearDown(() {
|
|
||||||
reset(sharedPreferences);
|
|
||||||
});
|
|
||||||
|
|
||||||
group('migrateOldKeys()', () {
|
|
||||||
test('no legacy keys', () async {
|
|
||||||
when(() => sharedPreferences.getInt("curIsoIndex")).thenReturn(null);
|
|
||||||
when(() => sharedPreferences.getInt("curndIndex")).thenReturn(null);
|
|
||||||
when(() => sharedPreferences.getDouble("cameraCalibr")).thenReturn(null);
|
|
||||||
when(() => sharedPreferences.getDouble("sensorCalibr")).thenReturn(null);
|
|
||||||
when(() => sharedPreferences.getBool("vibrate")).thenReturn(null);
|
|
||||||
|
|
||||||
when(() => sharedPreferences.remove("curIsoIndex")).thenAnswer((_) async => true);
|
|
||||||
when(() => sharedPreferences.remove("curndIndex")).thenAnswer((_) async => true);
|
|
||||||
when(() => sharedPreferences.remove("cameraCalibr")).thenAnswer((_) async => true);
|
|
||||||
when(() => sharedPreferences.remove("sensorCalibr")).thenAnswer((_) async => true);
|
|
||||||
when(() => sharedPreferences.remove("vibrate")).thenAnswer((_) async => true);
|
|
||||||
|
|
||||||
await service.migrateOldKeys();
|
|
||||||
|
|
||||||
verifyNever(() => sharedPreferences.remove("curIsoIndex"));
|
|
||||||
verifyNever(() => sharedPreferences.remove("curndIndex"));
|
|
||||||
verifyNever(() => sharedPreferences.remove("cameraCalibr"));
|
|
||||||
verifyNever(() => sharedPreferences.remove("sensorCalibr"));
|
|
||||||
verifyNever(() => sharedPreferences.remove("vibrate"));
|
|
||||||
});
|
|
||||||
|
|
||||||
test('migrate all keys', () async {
|
|
||||||
when(() => sharedPreferences.getInt("curIsoIndex")).thenReturn(1);
|
|
||||||
when(() => sharedPreferences.getInt("curndIndex")).thenReturn(0);
|
|
||||||
when(() => sharedPreferences.getDouble("cameraCalibr")).thenReturn(1.0);
|
|
||||||
when(() => sharedPreferences.getDouble("sensorCalibr")).thenReturn(-1.0);
|
|
||||||
when(() => sharedPreferences.getBool("vibrate")).thenReturn(false);
|
|
||||||
|
|
||||||
when(
|
|
||||||
() => sharedPreferences.setInt(UserPreferencesService.isoKey, IsoValue.values[1].value),
|
|
||||||
).thenAnswer((_) => Future.value(true));
|
|
||||||
when(
|
|
||||||
() => sharedPreferences.setInt(UserPreferencesService.ndFilterKey, NdValue.values[0].value),
|
|
||||||
).thenAnswer((_) => Future.value(true));
|
|
||||||
when(
|
|
||||||
() => sharedPreferences.setDouble(UserPreferencesService.cameraEvCalibrationKey, 1.0),
|
|
||||||
).thenAnswer((_) => Future.value(true));
|
|
||||||
when(
|
|
||||||
() => sharedPreferences.setDouble(UserPreferencesService.lightSensorEvCalibrationKey, -1.0),
|
|
||||||
).thenAnswer((_) => Future.value(true));
|
|
||||||
when(
|
|
||||||
() => sharedPreferences.setBool(UserPreferencesService.hapticsKey, false),
|
|
||||||
).thenAnswer((_) => Future.value(true));
|
|
||||||
|
|
||||||
when(() => sharedPreferences.remove("curIsoIndex")).thenAnswer((_) async => true);
|
|
||||||
when(() => sharedPreferences.remove("curndIndex")).thenAnswer((_) async => true);
|
|
||||||
when(() => sharedPreferences.remove("cameraCalibr")).thenAnswer((_) async => true);
|
|
||||||
when(() => sharedPreferences.remove("sensorCalibr")).thenAnswer((_) async => true);
|
|
||||||
when(() => sharedPreferences.remove("vibrate")).thenAnswer((_) async => true);
|
|
||||||
|
|
||||||
await service.migrateOldKeys();
|
|
||||||
|
|
||||||
verify(() => sharedPreferences.remove("curIsoIndex")).called(1);
|
|
||||||
verify(() => sharedPreferences.remove("curndIndex")).called(1);
|
|
||||||
verify(() => sharedPreferences.remove("cameraCalibr")).called(1);
|
|
||||||
verify(() => sharedPreferences.remove("sensorCalibr")).called(1);
|
|
||||||
verify(() => sharedPreferences.remove("vibrate")).called(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('iso', () {
|
|
||||||
test('get default', () {
|
|
||||||
when(() => sharedPreferences.getInt(UserPreferencesService.isoKey)).thenReturn(null);
|
|
||||||
expect(service.iso, const IsoValue(100, StopType.full));
|
|
||||||
});
|
|
||||||
|
|
||||||
test('get', () {
|
|
||||||
when(() => sharedPreferences.getInt(UserPreferencesService.isoKey)).thenReturn(100);
|
|
||||||
expect(service.iso, const IsoValue(100, StopType.full));
|
|
||||||
});
|
|
||||||
|
|
||||||
test('set', () {
|
|
||||||
when(() => sharedPreferences.setInt(UserPreferencesService.isoKey, 200))
|
|
||||||
.thenAnswer((_) => Future.value(true));
|
|
||||||
service.iso = const IsoValue(200, StopType.full);
|
|
||||||
verify(() => sharedPreferences.setInt(UserPreferencesService.isoKey, 200)).called(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('ndFilter', () {
|
|
||||||
test('get default', () {
|
|
||||||
when(() => sharedPreferences.getInt(UserPreferencesService.ndFilterKey)).thenReturn(null);
|
|
||||||
expect(service.ndFilter, const NdValue(0));
|
|
||||||
});
|
|
||||||
|
|
||||||
test('get', () {
|
|
||||||
when(() => sharedPreferences.getInt(UserPreferencesService.ndFilterKey)).thenReturn(4);
|
|
||||||
expect(service.ndFilter, const NdValue(4));
|
|
||||||
});
|
|
||||||
|
|
||||||
test('set', () {
|
|
||||||
when(() => sharedPreferences.setInt(UserPreferencesService.ndFilterKey, 0))
|
|
||||||
.thenAnswer((_) => Future.value(true));
|
|
||||||
service.ndFilter = const NdValue(0);
|
|
||||||
verify(() => sharedPreferences.setInt(UserPreferencesService.ndFilterKey, 0)).called(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('evSourceType', () {
|
|
||||||
test('get default', () {
|
|
||||||
when(() => sharedPreferences.getInt(UserPreferencesService.evSourceTypeKey)).thenReturn(null);
|
|
||||||
expect(service.evSourceType, EvSourceType.camera);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('get', () {
|
|
||||||
when(() => sharedPreferences.getInt(UserPreferencesService.evSourceTypeKey)).thenReturn(1);
|
|
||||||
expect(service.evSourceType, EvSourceType.sensor);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('set', () {
|
|
||||||
when(() => sharedPreferences.setInt(UserPreferencesService.evSourceTypeKey, 1))
|
|
||||||
.thenAnswer((_) => Future.value(true));
|
|
||||||
service.evSourceType = EvSourceType.sensor;
|
|
||||||
verify(() => sharedPreferences.setInt(UserPreferencesService.evSourceTypeKey, 1)).called(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('caffeine', () {
|
|
||||||
test('get default', () {
|
|
||||||
when(() => sharedPreferences.getBool(UserPreferencesService.caffeineKey)).thenReturn(null);
|
|
||||||
expect(service.caffeine, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('get', () {
|
|
||||||
when(() => sharedPreferences.getBool(UserPreferencesService.caffeineKey)).thenReturn(true);
|
|
||||||
expect(service.caffeine, true);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('set', () {
|
|
||||||
when(() => sharedPreferences.setBool(UserPreferencesService.caffeineKey, false))
|
|
||||||
.thenAnswer((_) => Future.value(true));
|
|
||||||
service.caffeine = false;
|
|
||||||
verify(() => sharedPreferences.setBool(UserPreferencesService.caffeineKey, false)).called(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('stopType', () {
|
|
||||||
test('get default', () {
|
|
||||||
when(() => sharedPreferences.getInt(UserPreferencesService.stopTypeKey)).thenReturn(null);
|
|
||||||
expect(service.stopType, StopType.third);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('get', () {
|
|
||||||
when(() => sharedPreferences.getInt(UserPreferencesService.stopTypeKey)).thenReturn(1);
|
|
||||||
expect(service.stopType, StopType.half);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('set', () {
|
|
||||||
when(() => sharedPreferences.setInt(UserPreferencesService.stopTypeKey, 0))
|
|
||||||
.thenAnswer((_) => Future.value(true));
|
|
||||||
service.stopType = StopType.full;
|
|
||||||
verify(() => sharedPreferences.setInt(UserPreferencesService.stopTypeKey, 0)).called(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('meteringScreenLayout', () {
|
|
||||||
test('get default', () {
|
|
||||||
when(
|
|
||||||
() => sharedPreferences.getString(UserPreferencesService.meteringScreenLayoutKey),
|
|
||||||
).thenReturn(null);
|
|
||||||
expect(
|
|
||||||
service.meteringScreenLayout,
|
|
||||||
{
|
|
||||||
MeteringScreenLayoutFeature.extremeExposurePairs: true,
|
|
||||||
MeteringScreenLayoutFeature.filmPicker: true,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('get', () {
|
|
||||||
when(
|
|
||||||
() => sharedPreferences.getString(UserPreferencesService.meteringScreenLayoutKey),
|
|
||||||
).thenReturn("""{"0":false,"1":true}""");
|
|
||||||
expect(
|
|
||||||
service.meteringScreenLayout,
|
|
||||||
{
|
|
||||||
MeteringScreenLayoutFeature.extremeExposurePairs: false,
|
|
||||||
MeteringScreenLayoutFeature.filmPicker: true,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('set', () {
|
|
||||||
when(
|
|
||||||
() => sharedPreferences.setString(
|
|
||||||
UserPreferencesService.meteringScreenLayoutKey,
|
|
||||||
"""{"0":false,"1":true}""",
|
|
||||||
),
|
|
||||||
).thenAnswer((_) => Future.value(true));
|
|
||||||
service.meteringScreenLayout = {
|
|
||||||
MeteringScreenLayoutFeature.extremeExposurePairs: false,
|
|
||||||
MeteringScreenLayoutFeature.filmPicker: true,
|
|
||||||
};
|
|
||||||
verify(
|
|
||||||
() => sharedPreferences.setString(
|
|
||||||
UserPreferencesService.meteringScreenLayoutKey,
|
|
||||||
"""{"0":false,"1":true}""",
|
|
||||||
),
|
|
||||||
).called(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('haptics', () {
|
|
||||||
test('get default', () {
|
|
||||||
when(() => sharedPreferences.getBool(UserPreferencesService.hapticsKey)).thenReturn(null);
|
|
||||||
expect(service.haptics, true);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('get', () {
|
|
||||||
when(() => sharedPreferences.getBool(UserPreferencesService.hapticsKey)).thenReturn(true);
|
|
||||||
expect(service.haptics, true);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('set', () {
|
|
||||||
when(() => sharedPreferences.setBool(UserPreferencesService.hapticsKey, false))
|
|
||||||
.thenAnswer((_) => Future.value(true));
|
|
||||||
service.haptics = false;
|
|
||||||
verify(() => sharedPreferences.setBool(UserPreferencesService.hapticsKey, false)).called(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('locale', () {
|
|
||||||
test('get default', () {
|
|
||||||
when(() => sharedPreferences.getString(UserPreferencesService.localeKey)).thenReturn(null);
|
|
||||||
expect(service.locale, SupportedLocale.en);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('get', () {
|
|
||||||
when(() => sharedPreferences.getString(UserPreferencesService.localeKey))
|
|
||||||
.thenReturn('SupportedLocale.ru');
|
|
||||||
expect(service.locale, SupportedLocale.ru);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('set', () {
|
|
||||||
when(
|
|
||||||
() => sharedPreferences.setString(UserPreferencesService.localeKey, 'SupportedLocale.en'),
|
|
||||||
).thenAnswer((_) => Future.value(true));
|
|
||||||
service.locale = SupportedLocale.en;
|
|
||||||
verify(
|
|
||||||
() => sharedPreferences.setString(UserPreferencesService.localeKey, 'SupportedLocale.en'),
|
|
||||||
).called(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('cameraEvCalibration', () {
|
|
||||||
test('get default', () {
|
|
||||||
when(() => sharedPreferences.getDouble(UserPreferencesService.cameraEvCalibrationKey))
|
|
||||||
.thenReturn(null);
|
|
||||||
expect(service.cameraEvCalibration, 0.0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('get', () {
|
|
||||||
when(() => sharedPreferences.getDouble(UserPreferencesService.cameraEvCalibrationKey))
|
|
||||||
.thenReturn(2.0);
|
|
||||||
expect(service.cameraEvCalibration, 2.0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('set', () {
|
|
||||||
when(
|
|
||||||
() => sharedPreferences.setDouble(UserPreferencesService.cameraEvCalibrationKey, 1.0),
|
|
||||||
).thenAnswer((_) => Future.value(true));
|
|
||||||
service.cameraEvCalibration = 1.0;
|
|
||||||
verify(
|
|
||||||
() => sharedPreferences.setDouble(UserPreferencesService.cameraEvCalibrationKey, 1.0),
|
|
||||||
).called(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('lightSensorEvCalibration', () {
|
|
||||||
test('get default', () {
|
|
||||||
when(() => sharedPreferences.getDouble(UserPreferencesService.lightSensorEvCalibrationKey))
|
|
||||||
.thenReturn(null);
|
|
||||||
expect(service.lightSensorEvCalibration, 0.0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('get', () {
|
|
||||||
when(() => sharedPreferences.getDouble(UserPreferencesService.lightSensorEvCalibrationKey))
|
|
||||||
.thenReturn(2.0);
|
|
||||||
expect(service.lightSensorEvCalibration, 2.0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('set', () {
|
|
||||||
when(
|
|
||||||
() => sharedPreferences.setDouble(UserPreferencesService.lightSensorEvCalibrationKey, 1.0),
|
|
||||||
).thenAnswer((_) => Future.value(true));
|
|
||||||
service.lightSensorEvCalibration = 1.0;
|
|
||||||
verify(
|
|
||||||
() => sharedPreferences.setDouble(UserPreferencesService.lightSensorEvCalibrationKey, 1.0),
|
|
||||||
).called(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('themeType', () {
|
|
||||||
test('get default', () {
|
|
||||||
when(() => sharedPreferences.getInt(UserPreferencesService.themeTypeKey)).thenReturn(null);
|
|
||||||
expect(service.themeType, ThemeType.light);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('get', () {
|
|
||||||
when(() => sharedPreferences.getInt(UserPreferencesService.themeTypeKey)).thenReturn(1);
|
|
||||||
expect(service.themeType, ThemeType.dark);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('set', () {
|
|
||||||
when(
|
|
||||||
() => sharedPreferences.setInt(UserPreferencesService.themeTypeKey, 1),
|
|
||||||
).thenAnswer((_) => Future.value(true));
|
|
||||||
service.themeType = ThemeType.dark;
|
|
||||||
verify(
|
|
||||||
() => sharedPreferences.setInt(UserPreferencesService.themeTypeKey, 1),
|
|
||||||
).called(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('primaryColor', () {
|
|
||||||
test('get default', () {
|
|
||||||
when(() => sharedPreferences.getInt(UserPreferencesService.primaryColorKey)).thenReturn(null);
|
|
||||||
expect(service.primaryColor, ThemeProvider.primaryColorsList[5]);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('get', () {
|
|
||||||
when(() => sharedPreferences.getInt(UserPreferencesService.primaryColorKey))
|
|
||||||
.thenReturn(0xff9c27b0);
|
|
||||||
expect(service.primaryColor, ThemeProvider.primaryColorsList[2]);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('set', () {
|
|
||||||
when(
|
|
||||||
() => sharedPreferences.setInt(UserPreferencesService.primaryColorKey, 0xff000000),
|
|
||||||
).thenAnswer((_) => Future.value(true));
|
|
||||||
service.primaryColor = Colors.black;
|
|
||||||
verify(
|
|
||||||
() => sharedPreferences.setInt(UserPreferencesService.primaryColorKey, 0xff000000),
|
|
||||||
).called(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('dynamicColor', () {
|
|
||||||
test('get default', () {
|
|
||||||
when(() => sharedPreferences.getBool(UserPreferencesService.dynamicColorKey))
|
|
||||||
.thenReturn(null);
|
|
||||||
expect(service.dynamicColor, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('get', () {
|
|
||||||
when(() => sharedPreferences.getBool(UserPreferencesService.dynamicColorKey))
|
|
||||||
.thenReturn(true);
|
|
||||||
expect(service.dynamicColor, true);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('set', () {
|
|
||||||
when(() => sharedPreferences.setBool(UserPreferencesService.dynamicColorKey, false))
|
|
||||||
.thenAnswer((_) => Future.value(true));
|
|
||||||
service.dynamicColor = false;
|
|
||||||
verify(() => sharedPreferences.setBool(UserPreferencesService.dynamicColorKey, false))
|
|
||||||
.called(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('film', () {
|
|
||||||
test('get default', () {
|
|
||||||
when(() => sharedPreferences.getString(UserPreferencesService.filmKey)).thenReturn(null);
|
|
||||||
expect(service.film, Film.values.first);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('get', () {
|
|
||||||
when(() => sharedPreferences.getString(UserPreferencesService.filmKey))
|
|
||||||
.thenReturn('Fomapan ACTION 400');
|
|
||||||
expect(service.film, const FomapanFilm.action400());
|
|
||||||
});
|
|
||||||
|
|
||||||
test('set', () {
|
|
||||||
when(() => sharedPreferences.setString(UserPreferencesService.filmKey, 'Fomapan ACTION 400'))
|
|
||||||
.thenAnswer((_) => Future.value(true));
|
|
||||||
service.film = const FomapanFilm.action400();
|
|
||||||
verify(
|
|
||||||
() => sharedPreferences.setString(UserPreferencesService.filmKey, 'Fomapan ACTION 400'),
|
|
||||||
).called(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
Loading…
Reference in a new issue