Compare commits

...

280 commits

Author SHA1 Message Date
Vadim
f820f9fbba
ML-218 Changing app resets EV and Zoom values ()
* preserve camera controls values after controller dispose

* notify camera bloc about equipment profile changes

* fixed tests

* lint
2025-05-04 11:21:37 +02:00
Vadim
d6cd537ffd
Force code sign for iOS workflow () 2025-04-02 11:58:21 +02:00
github-actions[bot]
91f90ae8e8 Release v1.0.4 2025-04-01 22:40:02 +00:00
Vadim
79f702f7ea
ML-228 Name textfield keeps focus after editing on other sections ()
* unfocus textfield when tapped outside

* autofocus equipment profile name

* upload diagnostic screenshots

* typo

* wip

* typo

* more diagnostic screenshots

* removed diagnostic screenshots

* returned diagnostic screenshots

* skip failing step (wip)

* cleanup
2025-04-01 22:35:24 +02:00
Linus von Drenkmann
f0110e0edf
Add German translation ()
* l10n: add German translation

* l10n: add German to supported locales

* l10n(german): improve translation of "none"

* l10n(german): change about title

* style: alphabetical sorting of languages
2025-03-22 11:23:18 +01:00
Vadim
0e45d98060
ML-221 Spot Metering only available when Histogram is enabled () 2025-03-17 22:43:00 +01:00
Vadim
cf471afdfd
Use Firebase mocks to setup the repo () 2025-03-17 22:18:55 +01:00
Vadim
d95b811d6c
Added script to setup the repo & updated README.md ()
* added script to setup the repo

* moved scripts to scripts folder

* Update README.md

* added macOS disclaimer
2025-03-17 21:35:33 +01:00
Vadim
2dee63e78e
Updated screenshots with v1.0.3 ()
* fixed errors

* removed autofocus from name textfield

* fixed equipment profiles find

* updated ios screenshots

* deleted redundant "light_equipment-profiles-iso-picker"

* merged scripts per platform

* updated android screenshots

* fixed flutter version

* Update README.md

* skip codesign for PR ipa
2025-02-16 12:41:56 +01:00
github-actions[bot]
5856100634 Release v1.0.3 2025-01-28 09:03:42 +00:00
Vadim
492cbaa7ee
ML-209 Camera preview orientation is wrong ()
* lock orientation to `portraitUp`

* removed custom rotator for camera preview

* downgraded to Flutter 3.24.5

* purchasable product

* updated goldens

* skip artifact upload for PR checks

* iap 2.1.3

* Update update_goldens.sh
2025-01-27 21:32:41 +01:00
ScaredCube
461efc7ffd
Modify Chinese Translations () 2025-01-27 21:11:16 +01:00
Vadim
c9bc8bc55d
PR check workflow improvements ()
* fixed builds being pushed to main

* restore firebase options in workflows

* moved firebase options to gitignore

* restore firebase options in workflows

* moved firebase options to gitignore

* migrated to artifacts v4

* split analyze workflow for stub

* skip artifact upload for PR checks

* typo

* updated firebase stub

* stub check

* typo

* Revert "stub check"

This reverts commit ff2b7cdc23.
2025-01-27 20:58:59 +01:00
github-actions[bot]
c6c52981ee Release v1.0.2 2025-01-23 17:57:01 +00:00
Vadim
6ddb779679
Migrated to artifacts v4 ()
* fixed builds being pushed to main

* restore firebase options in workflows

* moved firebase options to gitignore

* restore firebase options in workflows

* moved firebase options to gitignore

* migrated to artifacts v4
2025-01-23 18:41:16 +01:00
Vadim
38407d6c08
Moved Firebase options to .gitignore ()
* fixed builds being pushed to main

* restore firebase options in workflows

* moved firebase options to gitignore
2025-01-23 18:24:32 +01:00
Vadim
8ecab836a3 ML-209 Camera preview orientation is wrong ()
* lock orientation to `portraitUp`

* removed custom rotator for camera preview
2025-01-23 18:05:39 +01:00
Vadim
2439f7bfff Fixed builds being pushed to main () 2025-01-23 18:05:39 +01:00
github-actions[bot]
5e8f66d75c Release v1.0.1 2025-01-21 19:04:54 +00:00
Vadim
75dc9aaf13
Added builds to CI ()
* Update README.md

* Set exact Flutter version for workflows

* Added stub `DefaultFirebaseOptions`

* Fixed `rm`

* Removed `rm`

* Update .gitignore

* Added readable name to ci workflow

* Build -> Development

* Update ci.yml

* Extract merged native libraries

* More descriptive run name

* Delete no longer used artifacts

* Replaced "Build ..." flow with "Create release"

* renamed other flows

* try using script for iap stub

* typo

* typo

* typo

* removed working dir

* added comment to stub_iap.sh

* checkout first

* increment build number by script

* Update increment_build_number.sh

* fixed iap repo

* stub

* updated stub script to work with tags

* depend on step conclusion

* check PR number

* run integration tests before build

* reuse Build Android workflow

* added stage backend option

* reuse Build iOS workflow

* temporeraly skip release jobs

* [ios] use distribution profile for release builds

* temporary skip tests

* typo

* checkout actions

* incremented macos runner version

* Restore GoogleService-Info.plist

* Restore firebase_app_id_file.json

* style

* separated android and ios builds

* fixed invalid workflow

* simplified release workflow tree

* fixed android keystore path

* enabled integration tests

* added option to skip integration tests

* fixed android folders...

* enabled releases

* increment build number for ios

* upload ipa to app store

* test ipa upload

* typo

* try to force ipa upload

* removed flavor from ipa artefact name

* try manual ipa upload

* switched to ubuntu for upload

* decode to repo

* Update create_release.yml

* auth with username + password

* reverted temporary settings

* typo

* disable pre-release integration tests by default

* fixed integration tests

* increased integration tests timeout

* delete ipa after upload

* delete all artifacts after the run

* fixed integration tests

* reduce integration tests timeout

* build apk with latest macos runner

* allow to skip release to one of the stores

* added build checks to PR checks

* fixed inputs naming

* increased jvm heap
2025-01-21 19:43:14 +01:00
Vadim
e7b0726504 Download apk before creating GitHub release 2025-01-21 09:00:01 +01:00
Vadim
b073391491 Set compileSdkVersion to 35 2025-01-21 08:55:41 +01:00
Vadim
e334f0f8da
ML-175 Improved logging for missing EXIF fields ()
* include only the necessary values in logs

* added runtime type to iso
2025-01-20 20:03:02 +01:00
Vadim
aa29ef28e6
ML-205 Cannot restore purchases ()
* disallow backup

* migrated to iap 2.1.2
2025-01-20 19:46:50 +01:00
Vadim
fb58b6cd9f
Upgrade project to the latest stable Flutter version ()
* fixed fvm path typo

* Update pubspec.yaml

* version control pubspec.lock

* fixed ios build

* deleted `ExpandableSectionList`

* removed redundant default cases

* avoided async gaps

* replaced deprecated color value getter

* `WillPopScope` -> `PopScope`

* removed theme deprecations

* replaced text scale deprecation

* updated goldens

* updated flutter version across workflows

* [android] migrated to the new gradle

* upgraded dependencies

* [android] fixed build

* [ios] fixed build

* updated config

* allow release notes to fail

* updated stub pubspec

* [android] use java 17

* [ios] enable flutterfire

* added firebase.json to secrets

* typo

* update color utils

* use exact versions

* reverted color utils

* updated goldens
2025-01-20 19:32:57 +01:00
github-actions[bot]
fd97fc7fef Release v1.0.0 2024-11-17 09:13:00 +00:00
Vadim
38f99afa8c Create beta releases with CD 2024-11-17 09:50:16 +01:00
Vadim
c0e26b8840
ML-196 Allow to select equipment profile in use ()
* fixed equipment profile pickers updates
2024-11-17 09:49:01 +01:00
github-actions[bot]
1e4aa33b67 Release v1.0.0 2024-11-12 11:42:03 +00:00
Vadim
de011c5ff3 Increased integration tests timeout 2024-11-12 11:03:36 +01:00
Vadim
bfe3dc0ef4 Added beta release track to CD 2024-11-11 19:04:08 +01:00
Vadim
1d22ec5439
Removed language switch from release notes dialog ()
* Removed language switch from release notes dialog
2024-11-11 18:51:16 +01:00
Vadim
30418a9cfd
ML-196 Allow to select equipment profile in use ()
* integrated `EquipmentProfilesStorageService`

* implemented `EquipmentProfileEditScreen`

* added equipment profiles screens to navigation

* fixed tests

* fixed splashscreen removal

* replaced old `EquipmentProfilesScreen`

* typo

* use outlined icons

* fixed storage mock for integration tests

* recovered copy feature for profiles

* added profile deletion to e2e test

* added translations

* added film translations

* wip

* add ability to toggle equipment profiles

* lints

* fixed tests

* sync with iap rename

* use `Toggleable` from resources

* use iap 2.1.0

* use outlined edit icon
2024-11-11 17:20:12 +01:00
Vadim
c66381f813
ML-191 Add an ability to add a generic film, that will accept a formula ()
* sync with resources

* separated `ExpandableSectionList` as widget

* fixed generic type

* implemented `FilmsScreen` (wip)

* made `SliverScreen` title a widget

* [`FilmEditScreen`] wip

* [`FilmEditScreen`] added validation

* fixed title overflow for `SliverScreen`

* [`FilmEditScreen`] separated add and edit blocs

* [`FilmEditScreen`] split into separate components

* added bottom widget to `SliverScreen`

* implemented films list tabs fo `FilmsScreen`

* added films screen to navigation

* replaced explicit routes names with enum values

* implemented CRUD for custom films

* added placeholder for empty custom films list

* added `FilmsStorageService`

* fixed unit tests

* fixed integration tests

* lint

* fixed golden tests

* added iap stub methods

* added custom films to features list

* use 2.0.0 resouces

* fixed film picket tests

* migrated to iap 1.0.1

* autofocus film name field

* wait for the film to edited

* migrated to iap 1.1.0

* typo

* wait for storage initialization

* migrated to iap 1.1.1

* fixed films initialization

* added conditions to films model `updateShouldNotifyDependent`

* typo

* fixed select film discard notify

* covered films model `updateShouldNotifyDependent`
2024-11-03 20:16:01 +01:00
github-actions[bot]
d938be61c4 Release v0.21.0 2024-10-09 08:51:49 +00:00
Vadim
7639998df2 Incremented build number for iOS 2024-10-09 09:57:03 +02:00
Vadim
4e5cbc7759
Include generated release notes in builds ()
* create release notes from workflow input

* temp disable releases

* force builds

* include release notes in builds

* enabled releases
2024-10-08 19:53:15 +02:00
Vadim
191959b12b Fixed integration tests with iap stub 2024-10-08 09:54:22 +02:00
Vadim
b9c4796a7a
Returned release notes input to release workflow () 2024-10-07 20:26:29 +02:00
Vadim
1b3d6b2b90 Upgraded to m3_lightmeter_iap: 0.11.2 2024-10-07 19:44:15 +02:00
Vadim
98262fc4ee Upgraded to m3_lightmeter_resources: 1.4.0 2024-10-06 18:29:26 +02:00
Vadim
63ff6cc867
ML-189 Auto-downsize exposure pairs items for big display sizes ()
* added autosize text

* added more room for exposure pairs list

* downsize text only for long values
2024-09-23 16:08:30 +02:00
github-actions[bot]
66a38f2969 Release v0.20.0 2024-07-28 18:05:42 +00:00
Vadim
9100ae3066
Build Android using macos-latest runner ()
* build apk with latest macos runner
2024-07-28 18:52:44 +02:00
Vadim
006158c731 Added release notes 2024-07-28 14:42:09 +02:00
Vadim
9d5860a53f
ML-184 Make "Restore purchases" option more accessible ()
* moved "Restore purchases" to the Pro section

* updated goldens

* downgraded dependencies

* upgraded again

* added resources to dependency_overrides
2024-07-28 14:37:37 +02:00
Vadim
e53eca1831 Upgraded to m3_lightmeter_iap 0.11.1 2024-07-28 13:50:06 +02:00
Vadim
0e09c28150 Upgraded to m3_lightmeter_resources: 1.3.0 2024-07-28 13:26:09 +02:00
Vadim
a0f55c4a95 Upgraded targetSdkVersion to 34 2024-07-23 23:21:00 +02:00
Vadim
f0d707b071
Show Lightmeter Pro price before purchase ()
* Upgraded `targetSdkVersion` to 34

* added price to `IAPProduct`

* implemented `ProFeaturesScreen` (wip)

* finalized `ProFeaturesScreen` layout

* replaced `ProFeaturesDialog` with `ProFeaturesScreen`

* added translations

* fixed feature checkbox width calculation

* fixed tests

* separated android & ios features

* NPE

* changed "get pro" tile colors

* unified Lightmeter Pro related naming

* typo

* updated golden tests

* use iap 0.11.0

* revert unrelated changes

This reverts commit bae5ead8f0.

* lint

* adjusted eng translation

* updated goldens
2024-07-23 23:19:41 +02:00
github-actions[bot]
1e2cd8b5d2 Release v0.19.0 2024-05-23 12:07:37 +00:00
Vadim
90bfe7c7b8 Fixed integration tests 2024-05-23 11:34:11 +02:00
Vadim
7f8ea54c6e Fixed duplicate release notes dialog 2024-05-23 09:08:16 +02:00
Vadim
36d7e081f1 Reordered screenshots in README 2024-05-22 22:51:13 +02:00
Vadim
d4deae57ef Fixed release notes dialog logic 2024-05-22 22:50:47 +02:00
Vadim
881778b313
Show release notes after update ()
* replace generated release notes with pre-built assets

* implemented release notes dialog

* store release notes for version

* show release notes dialog after update

* added release notes dialog to settings

* allow blank values in settings

* updated release notes
2024-05-22 22:46:46 +02:00
Vadim
f62f658be8
Automated release screenshots generation ()
* added system overlays for iPhone 8 Plus & iPhone 13 Pro

* add device frame (wip)

* scale device frame (wip)

* add text to screenshots (wip)

* added screenshots config json

* reorganized screenshot models

* cleanup

* added fonts for dark screenshots

* typo

* store raw screenshots

* added standalone script to update screenshots

* wip

* refined screenshots naming

* skip metering layout dialog screenshot

* parse ipad name

* added assets for Pixel 6

* typo

* added text for incident light metering

* reorganized store script

* typo

* wip

* synced outlined icons

* added timer screen to screenshot generator

* constrained timer screen timeline for tablets

* added timer screenshot title

* typo

* revised scripts

* track release screenshots

* Update README.md

* iphone 6.5" -> iphone 6.7"

* Update google_play_resources.md

* softened screenshot font colors

* cleanup
2024-05-21 19:13:33 +02:00
Vadim
8c016e548b
Unified the app's color palette & icons ()
* unified scaffold background color

* unified components elevation

* use filled tonal icon buttons

* aligned slider colors with guidelines

* removed unused `CloseButton`

* migrated to outlined icons

* moved timer list tile to the top of the section

* updated goldens

* migrated to the latest material utils

* reaplced `SchemeTonalSpot` with `SchemeRainbow`

* fixed ruler slider ticks color

* update goldens

* fixed tests

* fixed scheme mapping and returned to `SchemeTonalSpot`
2024-05-20 17:08:37 +02:00
Vadim
5c27f726c5
ML-173 Add a timer for long exposures ()
* wip

* added start/stop button

* animated timeline

* fixed timer stop state

* added reset button (wip)

* added `onExposurePairTap` callback

* integrated `TimerScreen` to navigation

* separated `TimerTimeline`

* fixed timeline flickering

* added milliseconds to timer

* synchronized timeline with actual timer

* reused `BottomControlsBar`

* fixed default scaffold background color

* moved center button size to the bar itself

* display selected exposure pair on timer screen

* separated reusable `AnimatedCircluarButton`

* release camera when timer is opened

* added `TimerInteractor`

* added `TimerBloc` test

* fixed hours parsing

* added scenarios for timer golden test

* adjusted timer timeline colors

* show iso & nd values on timer screen

* automatically close timer screen after timeout

* added timer autostart

* reverted theme changes

* updated goldens

* typo

* removed timer screen auto-dismiss

* increased timer vibration duration

* replaced outlined locks

* increased 1/3 values font size
2024-05-07 19:24:51 +02:00
Vadim
bc7e6e14d0
ML-170 Show long shutter speeds for all selected aperture values ()
* generate exposures > 1"

* fixed unit tests

* added manual shutter speed to equipment profiles

* fixed integration tests

* fixed unit tests

* fixed long exposures overflow

* migrated to resources 1.2.0 and iap 0.10.0

* removed unnecessary loop

* fixed extreme exposure pairs test

* updated master screenshots

* fixed iap stub
2024-04-30 12:44:01 +02:00
Vadim
ec1f1eeeb4 Fixed release creation workflow 2024-04-19 17:03:45 +02:00
Vadim
6dd17961b5 Fixed Android screenshots generator 2024-04-19 16:59:00 +02:00
Vadim
d9ce47e0dd Show release version instead of "Version bump" 2024-04-15 18:27:56 +02:00
github-actions[bot]
5d7853c22e Version bump 2024-04-15 15:37:10 +00:00
Vadim
59977cc9b5
ML-134 Set Feature.showUnlockProOnMainScreen: true ()
* Set `Feature.showUnlockProOnMainScreen: true`

* update metering goldens
2024-04-15 13:18:50 +02:00
Vadim
d5f28ee5a4
ML-166 Fixed golden tests run on CI ()
* stub iap for goldens workflow

* typo

* Updated goldens

* don't push iap stub when updating goldens

* Update pubspec.yaml

* try explicit fonts

* Updated goldens

* set explicit font weights

* disable font smoothing

* run goldens on macos

* typo

* removed defaults from goldens workflow

* run pr check on macos-14

* removed smoothening reset

* Delete run_golden_tests.yml

* deleted fonts folder

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-04-12 10:43:19 +02:00
Vadim
27d56d1061
ML-166 Golden tests ()
* setup golden toolkit

* implemented `GoldenTestApplicationMock`

* added devices with dark theme

* implemented MeteringScreen golden test

* moved platform channel logic to app mock

* implemented SettingsScreen golden test

* gitignore golden tests failures

* Create dart_test.yaml

* adjusted `RulerSlider` ticks height

* set master screenshots

* run golden tests on ci

* fixed `LightSensorService` tests

* removed golden workflow call from PR check

* Update pr_check.yml
2024-04-12 08:07:20 +02:00
Vadim
2f8bb983d5
MLI-7 Manually restore purchases ()
* added `RestorePurchasesListTile`

* added `restorePurchases` to iap stub

* reordered settings

* migrated to iap 0.9.0

* migrated to iap 0.9.1

* use version in release commit

* Revert "use version in release commit"

This reverts commit 513b13eb96.

* migrated to iap 0.9.2

* allow manual restore if Pro features are not unlocked
2024-04-10 22:30:35 +02:00
Vadim
2117df2f11
ML-44 Save zoom level for equipment profile ()
* made zoom slider vertical & added more ticks to ruler

* show sliders values

* increased slider tappable area

* more accurate sliders values

* added zoom slider to equipment profiles settings

* split `EquipmentListTiles` widget

* set zoom on equipment profile change

* clamp zoom to the nearest value

* added missing translations

* added zoom checks to e2e test

* removed unused import
2024-04-07 10:54:57 +02:00
Vadim
bfd0bfe531
ML-108 First exposure metering seems to be wrong ()
* use latest `camera_android_camerax`

* fixed trailing commas

* moved ci/cd to 3.13.9

* removed focus & exposure fix

* fixed camera not being initialized on Android

* removed unused import
2024-04-06 19:14:37 +02:00
Vadim
2128e7c2e9 Fixed test coverage script 2024-03-17 20:18:00 +01:00
Vadim
d6c4240646 ML-157 Improve CI/CD ()
* Update README.md

* Set exact Flutter version for workflows

* Added stub `DefaultFirebaseOptions`

* Fixed `rm`

* Removed `rm`

* Update .gitignore

* Added readable name to ci workflow

* Build -> Development

* Update ci.yml

* Extract merged native libraries

* More descriptive run name

* Delete no longer used artifacts

* Replaced "Build ..." flow with "Create release"

* renamed other flows

* try using script for iap stub

* typo

* typo

* typo

* removed working dir

* added comment to stub_iap.sh

* checkout first

* increment build number by script

* Update increment_build_number.sh

* fixed iap repo

* stub

* updated stub script to work with tags

* depend on step conclusion

* check PR number

* run integration tests before build

* reuse Build Android workflow

* added stage backend option

* reuse Build iOS workflow

* temporeraly skip release jobs

* [ios] use distribution profile for release builds

* temporary skip tests

* typo

* checkout actions

* incremented macos runner version

* Restore GoogleService-Info.plist

* Restore firebase_app_id_file.json

* style

* separated android and ios builds

* fixed invalid workflow

* simplified release workflow tree

* fixed android keystore path

* enabled integration tests

* added option to skip integration tests

* fixed android folders...

* enabled releases

* increment build number for ios

* upload ipa to app store

* test ipa upload

* typo

* try to force ipa upload

* removed flavor from ipa artefact name

* try manual ipa upload

* switched to ubuntu for upload

* decode to repo

* Update create_release.yml

* auth with username + password

* reverted temporary settings

* typo

* disable pre-release integration tests by default

* fixed integration tests

* increased integration tests timeout

* delete ipa after upload

* delete all artifacts after the run

* fixed integration tests

* reduce integration tests timeout
2024-03-17 20:04:27 +01:00
Vadim
7787558713
ML-160 Integration tests ()
* test granting and revoking pro features

* extracted common widget tester actions

* test disabling & enabling of the metering screen layout features

* added integration tests to CI

* added integration tests to PR check

* allow matrix jobs to fail

* use base64 -d

* downgraded iphone version to the supported one

* use proper android device name

* typo in macos version

* upgraded iphone version to the supported one

* updated android compileSdkVersion

* added google services json restoration

* combined all tests in one file

* removed ipa signing for ios test

* debug prints :)

* lints

* refined tester extension and expectations

* e2e test (wip)

* added more expectations to e2e test

* changed pickers order a bit in e2e test

* added equipment profiles creation to e2e test

* added film selection to e2e test

* set android emulator API level to 32

* use flutter drive for integration tests

* removed app pre-build

* try running tests only for one platform

* added no-dds to flutter drive

* try running only on ios

* bumped macos version

* increased tests timeout

* set IPHONEOS_DEPLOYMENT_TARGET = 12.0

* removed prints

* Update Podfile

* restore firebase_app_id_file.json

* Delete run_integration_tests.sh

* run e2e with all tests

* reverted pr-check
2024-03-13 15:34:26 +01:00
Vadim
134af8ad28
ML-141 Prepare iOS release ()
* implemented `MockCameraContainerBloc` to stub camera on simulator

* [iOS] fixed camera preview aspect ratio

* place screenshots in platform-specific folders

* [iOS] updated buildable name

* [iOS] fixed stub image cover fit

* [iOS] implemented screenshots generator for all target devices

* store screenshots in _generated_ folder

* Update .gitignore

* Created "Build Prod .ipa" workflow

* added. certs to .ipa workflow

* test ipa building

* fixed provision cert path

* set provision profile in XCode

* set automatic signing for dev builds

* set ios version in Podfile

* renamed provision file

* renamed provision profile

* fixed cert folder...

* changed provision path

* typo

* typo

* try automatic signing

* use manual profile installation

* added export options

* typo

* increased timeout

* increased ipa timeout

* Update README.md

* typo

* [iOS] separated camera handling logic

* [iOS] fixed vibration

* migrated to http server iap

* [iOS] fixed histogram

* replaced distribution profile with development profile

* removed constants from env to the separate file

* removed duplicate launch schema

* fixed PR check workflow

* [iOS] set `ITSAppUsesNonExemptEncryption` to NO

* [iOS] removed java reference from "Build .ipa" workflow
2024-02-21 12:33:25 +01:00
Vadim
a1ce17d675
ML-154 Improved EXIF errors reporting ()
* removed unused analytics event & added `logCrash`

* added analytics to `RemoteConfigService`

* run app with `runZonedGuarded`

* added crash logging to `CameraContainerBloc`

* log product id for IAP errors

* typo

* log crashes in `RemoteConfigService`

* ignore silent `FlutterError`

* fixed `evFromImage` test

* fixed `showBuyProDialog` test

* log errors in console

* depend on iap 0.7.2

* Made errors non-fatal by default

* improved EXIF errors reporting

* fixed tests
2024-02-13 19:33:40 +01:00
Vadim
4f4b6cf1eb
ML-154 Made errors non-fatal by default ()
* removed unused analytics event & added `logCrash`

* added analytics to `RemoteConfigService`

* run app with `runZonedGuarded`

* added crash logging to `CameraContainerBloc`

* log product id for IAP errors

* typo

* log crashes in `RemoteConfigService`

* ignore silent `FlutterError`

* fixed `evFromImage` test

* fixed `showBuyProDialog` test

* log errors in console

* depend on iap 0.7.2

* Made errors non-fatal by default
2024-02-13 18:19:43 +01:00
github-actions[bot]
f965b99e1d Version bump 2024-01-27 22:34:29 +00:00
Vadim
fc37016770
ML-154 Improve Crashlytics reports ()
* removed unused analytics event & added `logCrash`

* added analytics to `RemoteConfigService`

* run app with `runZonedGuarded`

* added crash logging to `CameraContainerBloc`

* log product id for IAP errors

* typo

* log crashes in `RemoteConfigService`

* ignore silent `FlutterError`

* fixed `evFromImage` test

* fixed `showBuyProDialog` test

* log errors in console

* depend on iap 0.7.2
2024-01-27 23:20:53 +01:00
Vadim
9cb1cbaa90
ML-152 Added data extraction rules () 2024-01-26 13:18:07 +01:00
github-actions[bot]
de50b03df9 Version bump 2024-01-25 19:22:11 +00:00
Vadim
5fe6c46fd7 Updated Pro features description 2024-01-25 20:04:14 +01:00
ScaredCube
7d0c6684d1
Fix Chinese Translation Errors ()
Fix translation bugs
Fix redundant letter "s"
Fix wrong Traditional Chinese
2024-01-25 09:53:15 +01:00
github-actions[bot]
d66404e085 Version bump 2024-01-15 22:28:33 +00:00
Vadim
85c409fbe8
ML-134 Firebase Remote Config issues ()
* added try-catch to config fetch
2024-01-15 23:13:26 +01:00
Vadim
2b2a5441c7
ML-130 Added ff for the "Pro features" tile on the main screen ()
* added ff for Pro features tile on main screen
2024-01-15 22:57:40 +01:00
Vadim
8f5893c7d2
ML-143 EV100 indication ()
* added `showEV100` to user preferences

* integrated EV100 setting to UI

* available for pro

* replaced `IAPProducts.isPurchased` with context extension

* fixed `UserPreferencesProvider` tests

* EV100 -> Ev100
2024-01-15 20:47:10 +01:00
Vadim
73d0c32323
Hide Pro features from the metering screen ()
* implemented `MockCameraContainerBloc` to stub camera on simulator

* hide pro features from metering screen

* disable pro features in settings

* use closed child background color in `AnimatedDialog`

* adjust `AnimatedDialogPicker` to items count

* close `AnimatedDialog` through context

* cleanup

* fixed `ReadingValueContainer` text color

* removed legacy translations

* fixed tests

* fixed `AnimatedDialog` scaling

* added `evFromImage` test

* added no EXIF test to `evFromImage`
2024-01-13 18:20:58 +01:00
nathan musoke
a2b4c88256
Fixed typo in reciprocity description ()
grater -> greater

Co-authored-by: Vadim <44135514+vodemn@users.noreply.github.com>
2024-01-13 17:42:23 +01:00
Vadim
c80bac23b2
Added Support section to README.md
- Fixed Development section numeration
- Added contact email link
2024-01-04 18:39:44 +01:00
Vadim
1b4be83dda
Update PRIVACY_POLICY.md 2024-01-04 16:52:56 +01:00
ScaredCube
55b0e52d7f
Fix Chinese Translation Errors () 2023-12-01 14:54:44 +01:00
Vadim
561f849eea
Add app icon indicating dev build ()
* [Android] added (DEV) to dev flavor app name

* [Android] added `applicationIdSuffix` instead of explicit `applicationId`

* [Android] removed main/res for app to be able to see flavored resources

* replaced `flutter_launcher_icons` with `icons_launcher`

* [Android] generated icon for dev & prod flavors

* Create README.md

* [iOS] generated icons for dev & prod flavors

* [iOS] added (DEV) to dev flavor app name

* [iOS] cleanup
2023-11-21 21:37:23 +01:00
github-actions[bot]
e340327e32 Version bump 2023-11-14 12:30:33 +00:00
Vadim
19fc039723
ML-137 Dialogs improvements ()
* Force dialogs to have the same width

* Fix `DialogPicker` bouncing when the first selected item is near the end
2023-11-14 12:26:34 +01:00
Vadim
6566108994
ML-129 Spot metering ()
* imlemented `CameraSpotDetector`

* separated generic `DialogSwitch`

* added `CameraFeature` model

* added `CameraFeaturesListTile` to metering section

* added features dialog subtitles

* added long press to remove metering spot

* translations

* hide camera features for purchasable status

* hide `CameraHistogram` & `CameraSpotDetector` if purchasable

* bumped iap version

* fixed tests

* removed redundant camera state emission

* tests

* Fixed remote config initalization

* updated pro features description
2023-11-11 21:05:11 +01:00
github-actions[bot]
ddc7ec8c8b Version bump 2023-11-07 11:15:17 +00:00
Vadim
434327a7d0 Disable list tile onTap if IAP is pending 2023-11-07 12:03:38 +01:00
Vadim
068834bfe5
ML-134 Firebase Remote Config issues ()
* Unable to connect to the server

* internal remote config fetch error

* fixed tests
2023-11-07 11:57:36 +01:00
Vadim
3bb3f12641
ML-62 Utils tests ()
* removed redundant `UserPreferencesService` from `MeteringBloc`

* wip

* post-merge fixes

* `MeasureEvent` tests

* `MeasureEvent` tests revision

* `MeasureEvent` tests added timeout

* added stubs for other `MeteringBloc` events

* rewritten `MeteringBloc` logic

* wip

* `IsoChangedEvent` tests

* refined `IsoChangedEvent` tests

* `NdChangedEvent` tests

* `FilmChangedEvent` tests

* `MeteringCommunicationBloc` tests

* added test run to ci

* overriden `==` for `MeasuredState`

* `LuxMeteringEvent` tests

* refined `LuxMeteringEvent` tests

* rename

* wip

* wip

* `InitializeEvent`/`DeinitializeEvent` tests

* clamp minZoomLevel

* fixed `MeteringCommunicationBloc` tests

* wip

* `ZoomChangedEvent` tests

* `ExposureOffsetChangedEvent`/`ExposureOffsetResetEvent` tests

* renamed test groups

* added test coverage script

* improved `CameraContainerBloc` test coverage

* `EquipmentProfileChangedEvent` tests

* verify response vibration

* fixed running all tests

* `MeteringCommunicationBloc` equality tests

* `CameraContainerBloc` equality tests

* removed generated code from coverage

* `MeteringScreenLayoutFeature` tests

* `SupportedLocale` tests

* `Film` tests

* `CaffeineService` tests

* `UserPreferencesService` tests (wip)

* `LightSensorService` tests (wip)

* `migrateOldKeys()` tests

* ignore currently unused getters & setters

* gradle upgrade

* `reset(sharedPreferences);` calls count

* typo

* `MeteringInteractor` tests

* `SettingsInteractor` tests (wip)

* `MeteringInteractor` tests (wip)

* `SettingsInteractor` tests

* AnimatedDialog picker standalone tests

* Moved Animated dialog picker to widget tests

* `ExtremeExposurePairsContainer` widget test

* dialog picker test

* Match extreme exposure pairs & pairs list edge values

* `FilmPicker` widget tests

* fixed animated dialog picker tests

* add not hit files to coverage percentage

* Moved `EquipmentProfileProvider` & `FilmsProvider` to the main repo

* Synced _iap_ stub with repo

* `FilmsProvider` tests

* `EquipmentProfileProvider` tests

* Pass `availableFilms` to `FilmsProvider`

* `FilmPicker` tests

* removed unnecessary imports

* Metering layout features tests

* split integration tests by screens

* Films in use test

* mock light meter lux stream

* removed mockito mocks for integration tests

From no on these are the only mocks in use:
- Mock shared prefs initial values
- Mock platform responses (camera/light sensor)

* set sharedprefs mock without redundant group

* unified granting camera permission on Android

* fixed metering screen tests

* extracted common values

* `FilmPicker` integration tests

* fixed light sensor platform mocks

* wip

* removed integration tests for now

* moved screenshots generator to screenshots folder

* typo

* removed `MockIAPProductsProvider`

* implemented platform mocks for unit tests

* data/models/ 100% coverage

* `IsoValuePicker` tests

* `EquipmentProfileProvider` tests

* extended PR check timeout

* typo

* added storage action verification for `FilmsProvider` tests

* `UserPreferencesProvider` tests

* Update README.md

* added //coverage:ignore to `ServicesProvider`

* typo

* typo

* `toStringSignedAsFixed` tests

* `SelectableInheritedModel` tests

* removed unused `TextLineHeight` util

* `VolumeKeysNotifier` tests

* import

* `EquipmentProfileListener` tests

* typo

* split `EquipmentProfileListener` tests

* `showBuyProDialog` tests

* added `maybeOf` getter for iap stub
2023-11-02 17:40:47 +01:00
github-actions[bot]
37a3b79f04 Version bump 2023-11-01 10:16:41 +00:00
Vadim
d36db97959 Updated IAP version to fix network issue
https://github.com/flutter/flutter/issues/135540
2023-10-31 22:32:02 +01:00
Vadim
a52efcd341
ML-130 Integrate Firebase Remote Config ()
* implemented `RemoteConfigService`

* added alternative translations

* typo

* added `firebase_analytics`

* dim paid features list tiles

* log list tile tap instead of dialog

* implemented `RemoteConfigProvider`

* typo
2023-10-31 18:42:25 +01:00
Vadim
f3b08868be
ML-62 Providers tests + Platform & Application mocks ()
- Fixed test coverage calculation
- Removed `mockito` from the application mock
- Implemented platform channel mocks to mimic incident light metering
- Covered providers with unit tests
- Covered metering screen pickers with widget tests
- Laid foundation for integration tests
2023-10-20 16:12:43 +02:00
Vadim
0b51db642c
ML-126 Automate screenshots creation ()
* generate screenshots with ep set to None
2023-09-29 12:45:39 +02:00
Vadim
e0320b6704
ML-126 Automate screenshots creation ()
* Create screenshot_driver.dart

* wip

* deleted screenshots

* iap mock

* generate for 3 colors

* cleanup

* generate single dark screenshots

* snake_case

* added stub image for camera

* scroll to the first checkbox selected

* unstub iap

* cleanup

* Update generate_screenshots.dart

* typo
2023-09-28 23:29:33 +02:00
ScaredCube
5b1b0b0540
Update intl_zh.arb of new features () 2023-09-23 12:52:58 +02:00
github-actions[bot]
79105ab4f1 Version bump 2023-09-20 10:31:50 +00:00
Vadim
2a3c6b0b09
Added user feedback label to issue templates 2023-09-20 12:11:23 +02:00
Vadim
cc660de0c4
Fixed PR check ()
* updated stub script to work with tags

* depend on step conclusion

* check PR number
2023-09-20 11:58:04 +02:00
Vadim
4288be7d57 Use iap v0.4.0 2023-09-20 11:10:54 +02:00
github-actions[bot]
a5ad391273 Version bump 2023-09-19 18:45:24 +00:00
Vadim
9029379697 Merged Equipment section into Metering section 2023-09-19 17:26:32 +02:00
Vadim
abbc4c92de
ML-113 Add ability to copy equipment profile ()
* Display range values instead of values count

* copy equipment profile

* added `IconButton` tooltips
2023-09-18 16:59:53 +02:00
Vadim
0fbf252d9e
ML-117 Improve description of paid features ()
* wip

* added `LightmeterProSettingsSection`

* hide Pro section on purchase

* `ElevatedButton` -> `FilledButton`

* moved Pro description to iap/README.md

* intl

* disable only list tiles

* show iap dialog on every iap list tile
2023-09-17 22:29:02 +02:00
Vadim
cc9f162933
ML-107 Films filter ()
* added stub `FilmsProvider`

* moved dialogs to the shared folder

* typo

* separated `EquipmentSettingsSection`

* copy

* `IAPBuilder` -> `IAPListTile`

* moved `Film` to resources repo

* fixed films selection

* untied iso and selected film

* removed film from exposure pairs building

* indicate push/pull

* copy

* Update .gitignore

* fixed extreme exposure pairs reciprocity display

* sync with iap changes

* sync iap stub with iap changes

* added reciprocity description

* added workspace file

* Update .gitignore
2023-09-14 16:59:16 +02:00
github-actions[bot]
1be7c3be48 Version bump 2023-09-08 22:03:01 +00:00
Vadim
8415f4e515
ML-114 Metering container issues ()
* fixed top bar cutout shape

* update closed offset on layout change
2023-09-08 23:46:31 +02:00
Vadim
cf4373d854
Equipment profiles issues ()
* update equipment profile from dialog

* updated `MeteringScreenLayoutFeaturesDialog` translations
2023-09-08 22:25:13 +02:00
Vadim
4201d36abb Refined launch options 2023-09-03 13:06:30 +02:00
github-actions[bot]
429c0a53a2 Version bump 2023-09-02 21:13:17 +00:00
Vadim
f39177919c
Equipment profiles issues ()
* Fixed equipment profiles sections collapsing

* Fixed range picker dialog

* Refined equipment profiles sections handling
2023-09-02 22:29:35 +02:00
Vadim
bf3c8aa7c7 Fixed _Build .apk_ flow 2023-09-02 13:08:58 +02:00
Vadim
da4fcfc857
Fixed IAP stub in workflows ()
* try using script for iap stub

* typo

* typo

* typo

* removed working dir

* added comment to stub_iap.sh

* checkout first

* increment build number by script

* Update increment_build_number.sh

* fixed iap repo

* stub
2023-09-02 12:45:57 +02:00
Vadim
4bb080a144
Implemented IAP & Equipment profiles ()
* added equipment profiles to layout config

* calculate layout height based on `MeteringScreenLayoutFeature`

* Update cd_dev.yml

* Fixed equipment profile tile padding

* import

* `webfactory/ssh-agent`

* Update pubspec.yaml

* fixed `MeteringScreenLayoutConfigJson` tests

* fixed `UserPreferencesService` tests

* reset selected equipment profile when layout feature is disabled

* `IAPProductType.equipment` -> `IAPProductType.paidFeatures`

* updated packages versions

* Update shared_prefs_service.dart

* Fixed & tested exposure pairs list builder

* typo

* typo

* added iap repo stub

* Renamed `EquipmentProfileData` ->`EquipmentProfile`

* Moved `EquipmentProfileProvider` to iap repo

* Update README.md

* Fixed `EquipmentProfileListener`

* Improved `EquipmentProfilesListTile` statuses visualization

* Update README.md

* Update ci.yml

* Post-merge fixes

* typo

* Added workflow checks

* more sophisticated iap icons

* Include IAP by default

* added loader for `IAPProductStatus.pending`

* typo

* Added equipment profiles list placeholder

* typo

* separated `IconPlaceholder`

* improved `buildExposureValues` testing

* cleanup
2023-09-02 10:32:08 +02:00
github-actions[bot]
d364de4486 Version bump 2023-08-28 15:55:12 +00:00
Vadim
e1c320b804 Replaced user config with github-actions[bot] 2023-08-28 16:01:04 +02:00
Vadim
a9f8223e4a Added Firebase Analytics 2023-08-28 11:39:20 +02:00
Vadim
aee527dcca
Create FUNDING.yml 2023-08-20 11:14:37 +02:00
Vadim
5adcee00dd
ML-105 Hide providers from the widget tree ()
* Added `ServiceProviders` widget

* Added `EnumProviders` widget for enum values

* Moved `ThemeProvider` functionality to `EnumProviders`

* Style

* `EnumProviders` -> `UserPreferencesProvider`

* `ServiceProviders` -> `ServiceProvider`

* Moved `MeteringScreenLayoutProvider` functionality to `UserPreferencesProvider`

* typo

* Removed `InheritedModelAspectListener`

* TODO

* Removed Inherited Generics

* Removed redundant `LightmeterProviders`

* Removed redundant methods from `ServicesProvider`

* `_inheritFrom` -> `_inheritFromEnumsModel`

* Fixed `MeteringScreenLayoutConfig` updates

* Separated `_ThemeModel`

* typo

* `_EnumsModel` -> `_UserPreferencesModel`
2023-08-14 12:25:37 +02:00
Vadim
4917ee8aef
ML-61 Try to automate GP & Github releases via Github Actions ()
* Added option to create separate releases

* Removed branch condition

* Added default values to releases checkboxes

* Removed user fraction

* Remove .md extension for GP release

* More refined releases conditions

* Parse release name

* Create Google Play release name

* Checkout first

* Update create_release.yml

* Increment build number only for GH release

* Release with status `complete`

* typo
2023-08-10 12:42:31 +02:00
vodemn
6e3588a72e Version bump 2023-08-09 15:20:00 +00:00
Vadim
dafbc68288 Increased build job timeout 2023-08-09 17:06:47 +02:00
Vadim
bdb0442dd1 Fixed release jobs dependencies 2023-08-09 16:49:02 +02:00
Vadim
d41fa6fa84
ML-61 Download each artifact separately ()
* Download each artifact separately

* typo

* Updated setup-java action

* Extract merged native libs directly in GP release job
2023-08-09 16:39:41 +02:00
Vadim
b9412c7441
ML-61 Create Google Play release from Github actions ()
* Delete all artefacts after GP release

* Update create_release.yml

* Added release notes formatting

* Preserve release zip if GP release creation failed

* Create whatsnew folder
2023-08-09 12:24:12 +02:00
Vadim
d91441bac9
ML-95 Live histogram ()
* Removed redundant `stopImageStream()`
2023-08-08 11:46:43 +02:00
vodemn
9c11401175 Version bump 2023-08-07 14:59:47 +00:00
Vadim
737a9aa2c2
ML-98 Metering top bar cutout doesn't pass through taps ()
* replaced `OverflowBox` with `Stack`
2023-08-07 12:56:29 +02:00
Vadim
886188bb9e
ML-95 Live histogram ()
* Added histogram and separated camera view builder

* Added histogram to `MeteringScreenLayoutConfig`

* `ResolutionPreset.medium` -> `ResolutionPreset.low`

* Adjusted histogram paddings
2023-08-06 16:28:20 +02:00
Vadim
1310b78a54
ML-61 Delete artefacts after release creation ()
* Replaced "Build ..." flow with "Create new release"

* Renamed other flows
2023-08-05 21:11:23 +02:00
Vadim
8a71c8db13 Added switch animations to MeteringScreen 2023-08-04 16:17:40 +02:00
vodemn
6e1aaf5acf Version bump 2023-08-03 20:54:33 +00:00
Vadim
c12cfb1697 Lock & release focus when taking a picture 2023-08-03 22:46:01 +02:00
vodemn
50c2460f16 Version bump 2023-08-01 11:08:55 +00:00
Vadim
6a9036ce5e Camera is taking too long to take a picture 2023-08-01 12:58:43 +02:00
Vadim
40c670ad30
Updated README Build section ()
* Update README.md

* Set exact Flutter version for workflows

* Added stub `DefaultFirebaseOptions`

* Fixed `rm`

* Removed `rm`

* Update .gitignore

* Added readable name to ci workflow

* Build -> Development

* Update ci.yml
2023-07-25 17:31:01 +02:00
vodemn
119e079554 Version bump 2023-07-24 11:04:23 +00:00
ScaredCube
b02b50bac3
Fixed Chinese translation () 2023-07-24 12:16:35 +02:00
vodemn
dd5f551fd2 Version bump 2023-07-24 07:54:38 +00:00
ScaredCube
bb9b023fa7
Add Chinese language support ()
* Add Chinese language support

* Update intl_cn.arb

* Fixed some bugs

* Add Chinese language support

* renamed `cn` to `zh`

---------

Co-authored-by: Vadim <44135514+vodemn@users.noreply.github.com>
Co-authored-by: Vadim <vadim.turko@gmail.com>
2023-07-24 09:35:30 +02:00
Vadim
dbf1f09eb6 Renamed EquipmentProfileData -> EquipmentProfile 2023-07-24 09:08:37 +02:00
Vadim
b13acedebd
ML-62 Interactors tests ()
* removed redundant `UserPreferencesService` from `MeteringBloc`

* wip

* post-merge fixes

* `MeasureEvent` tests

* `MeasureEvent` tests revision

* `MeasureEvent` tests added timeout

* added stubs for other `MeteringBloc` events

* rewritten `MeteringBloc` logic

* wip

* `IsoChangedEvent` tests

* refined `IsoChangedEvent` tests

* `NdChangedEvent` tests

* `FilmChangedEvent` tests

* `MeteringCommunicationBloc` tests

* added test run to ci

* overriden `==` for `MeasuredState`

* `LuxMeteringEvent` tests

* refined `LuxMeteringEvent` tests

* rename

* wip

* wip

* `InitializeEvent`/`DeinitializeEvent` tests

* clamp minZoomLevel

* fixed `MeteringCommunicationBloc` tests

* wip

* `ZoomChangedEvent` tests

* `ExposureOffsetChangedEvent`/`ExposureOffsetResetEvent` tests

* renamed test groups

* added test coverage script

* improved `CameraContainerBloc` test coverage

* `EquipmentProfileChangedEvent` tests

* verify response vibration

* fixed running all tests

* `MeteringCommunicationBloc` equality tests

* `CameraContainerBloc` equality tests

* removed generated code from coverage

* `MeteringScreenLayoutFeature` tests

* `SupportedLocale` tests

* `Film` tests

* `CaffeineService` tests

* `UserPreferencesService` tests (wip)

* `LightSensorService` tests (wip)

* `migrateOldKeys()` tests

* ignore currently unused getters & setters

* gradle upgrade

* `reset(sharedPreferences);` calls count

* typo

* `MeteringInteractor` tests

* `SettingsInteractor` tests (wip)

* `MeteringInteractor` tests (wip)

* `SettingsInteractor` tests
2023-07-10 17:49:34 +02:00
Vadim
47f7b61230 Updated issuesReportUrl to lead to _/new/choose_ 2023-07-10 16:15:57 +02:00
Vadim
37fe6a4a5d
Update issue templates 2023-07-10 16:01:41 +02:00
Vadim
a25ccc0fad
Update issue templates 2023-07-10 13:08:03 +02:00
vodemn
b53603b3f5 Version bump 2023-07-09 11:50:22 +00:00
Vadim
e001c153fb
ML-11 Implement volume buttons actions ()
* [Android] wip

* implemented `VolumeEventsService`

* implemented `VolumeKeysListener` (wip)

* Added screenshots links

* [Android] nullable typo

* implemented `VolumeKeysNotifier`

* deinitialize camera when on Settings screen

* disable volume handling when on Settings screen

* used "platform" package to mock `isAndroid`

* init/deinit camera on settings open

* allow volume action override only on metering screen

* lints

* cleanup

* await dispose

* tests

* reduced `SwitchListTile.contentPadding`

* fixed tests

* removed `VolumeAction.zoom`

* added social preview

* typo

* fixed `CameraContainerBloc` tests

* added `Stream.empty()` tests
2023-07-09 13:39:33 +02:00
Vadim
ed83540dde
ML-61 Allow pushes from Github Action to protected branch ()
* Replaced zipping action

thedoctor0/zip-release@0.7.1 -> vimtor/action-zip@v1.1

* typo

* recursive: false

* typo

* typo

* debugSymbolLevel 'FULL'

* Update build.gradle

* Version bump

* wip

* wip

* `create-release` job

* removed changelog input

* added `needs`

* Version bump

* typo

* returned to macos-11 runner

* reverted pubspec version

* Version bump

* download artifacts

* Version bump

* extended artifacts path

* Version bump

* added LS

* Version bump

* Version bump

* rename files

* Version bump

* removed ls

* Version bump

* revert version

* typo

* added push to protected branch action

* run push on ubuntu-latest

* added branch name conditions

* Version bump

* typo

* Version bump
2023-06-28 17:53:54 +02:00
Vadim
79d6034894
ML-61 Update version in pubspec & create Github release from GitHub actions ()
* Replaced zipping action

thedoctor0/zip-release@0.7.1 -> vimtor/action-zip@v1.1

* typo

* recursive: false

* typo

* typo

* debugSymbolLevel 'FULL'

* Update build.gradle

* Version bump

* wip

* wip

* `create-release` job

* removed changelog input

* added `needs`

* Version bump

* typo

* returned to macos-11 runner

* reverted pubspec version

* Version bump

* download artifacts

* Version bump

* extended artifacts path

* Version bump

* added LS

* Version bump

* Version bump

* rename files

* Version bump

* removed ls

* Version bump

* revert version

* typo
2023-06-27 12:17:35 +02:00
Vadim
8ff387c5c5 Fixed com.google.gms:google-services version 2023-06-23 11:41:58 +02:00
Vadim
2735f0b66f
ML-81 Unsaved fractional stops ()
* save stop type to sharedPrefs

* tests
2023-06-23 10:47:34 +02:00
Vadim
0c58134733
ML-62 Services tests ()
* removed redundant `UserPreferencesService` from `MeteringBloc`

* wip

* post-merge fixes

* `MeasureEvent` tests

* `MeasureEvent` tests revision

* `MeasureEvent` tests added timeout

* added stubs for other `MeteringBloc` events

* rewritten `MeteringBloc` logic

* wip

* `IsoChangedEvent` tests

* refined `IsoChangedEvent` tests

* `NdChangedEvent` tests

* `FilmChangedEvent` tests

* `MeteringCommunicationBloc` tests

* added test run to ci

* overriden `==` for `MeasuredState`

* `LuxMeteringEvent` tests

* refined `LuxMeteringEvent` tests

* rename

* wip

* wip

* `InitializeEvent`/`DeinitializeEvent` tests

* clamp minZoomLevel

* fixed `MeteringCommunicationBloc` tests

* wip

* `ZoomChangedEvent` tests

* `ExposureOffsetChangedEvent`/`ExposureOffsetResetEvent` tests

* renamed test groups

* added test coverage script

* improved `CameraContainerBloc` test coverage

* `EquipmentProfileChangedEvent` tests

* verify response vibration

* fixed running all tests

* `MeteringCommunicationBloc` equality tests

* `CameraContainerBloc` equality tests

* removed generated code from coverage

* `MeteringScreenLayoutFeature` tests

* `SupportedLocale` tests

* `Film` tests

* `CaffeineService` tests

* `UserPreferencesService` tests (wip)

* `LightSensorService` tests (wip)

* `migrateOldKeys()` tests

* ignore currently unused getters & setters

* gradle upgrade

* `reset(sharedPreferences);` calls count

* typo
2023-06-23 10:35:33 +02:00
Vadim
a7b8de6912
ML-62 Models tests ()
* removed redundant `UserPreferencesService` from `MeteringBloc`

* wip

* post-merge fixes

* `MeasureEvent` tests

* `MeasureEvent` tests revision

* `MeasureEvent` tests added timeout

* added stubs for other `MeteringBloc` events

* rewritten `MeteringBloc` logic

* wip

* `IsoChangedEvent` tests

* refined `IsoChangedEvent` tests

* `NdChangedEvent` tests

* `FilmChangedEvent` tests

* `MeteringCommunicationBloc` tests

* added test run to ci

* overriden `==` for `MeasuredState`

* `LuxMeteringEvent` tests

* refined `LuxMeteringEvent` tests

* rename

* wip

* wip

* `InitializeEvent`/`DeinitializeEvent` tests

* clamp minZoomLevel

* fixed `MeteringCommunicationBloc` tests

* wip

* `ZoomChangedEvent` tests

* `ExposureOffsetChangedEvent`/`ExposureOffsetResetEvent` tests

* renamed test groups

* added test coverage script

* improved `CameraContainerBloc` test coverage

* `EquipmentProfileChangedEvent` tests

* verify response vibration

* fixed running all tests

* `MeteringCommunicationBloc` equality tests

* `CameraContainerBloc` equality tests

* removed generated code from coverage

* `MeteringScreenLayoutFeature` tests

* `SupportedLocale` tests

* `Film` tests
2023-06-21 11:29:36 +02:00
Vadim
4d1550f1e7 Version bump 2023-06-20 15:05:57 +02:00
Vadim
02ece15c5d
ML-61 Try using buildTypes.release.ndk.debugSymbolLevel 'FULL' ()
* Replaced zipping action

thedoctor0/zip-release@0.7.1 -> vimtor/action-zip@v1.1

* typo

* recursive: false

* typo

* typo

* debugSymbolLevel 'FULL'

* Update build.gradle
2023-06-20 14:48:28 +02:00
Vadim
74d0a7101c
ML-62 Bloc's tests ()
* removed redundant `UserPreferencesService` from `MeteringBloc`

* wip

* post-merge fixes

* `MeasureEvent` tests

* `MeasureEvent` tests revision

* `MeasureEvent` tests added timeout

* added stubs for other `MeteringBloc` events

* rewritten `MeteringBloc` logic

* wip

* `IsoChangedEvent` tests

* refined `IsoChangedEvent` tests

* `NdChangedEvent` tests

* `FilmChangedEvent` tests

* `MeteringCommunicationBloc` tests

* added test run to ci

* overriden `==` for `MeasuredState`

* `LuxMeteringEvent` tests

* refined `LuxMeteringEvent` tests

* rename

* wip

* wip

* `InitializeEvent`/`DeinitializeEvent` tests

* clamp minZoomLevel

* fixed `MeteringCommunicationBloc` tests

* wip

* `ZoomChangedEvent` tests

* `ExposureOffsetChangedEvent`/`ExposureOffsetResetEvent` tests

* renamed test groups

* added test coverage script

* improved `CameraContainerBloc` test coverage

* `EquipmentProfileChangedEvent` tests

* verify response vibration

* fixed running all tests

* `MeteringCommunicationBloc` equality tests

* `CameraContainerBloc` equality tests

* removed generated code from coverage
2023-06-20 08:43:49 +02:00
Vadim
0013125d68 Version bump 2023-06-08 10:23:35 +02:00
Vadim
ad8f0d895a Fixed film discard on ISO change 2023-06-08 10:23:16 +02:00
Vadim
1a64ef987b Version bump 2023-06-04 13:10:56 +02:00
Vadim
cdf7372913
ML-77 Redundant vibrations ()
* wip

* `MeteringScreenLayout = InheritedModelBase<MeteringScreenLayoutFeature, bool>`

* removed `Provider` from providers folder

* wip

* Update pubspec.yaml

* `context.get<MeteringInteractor>()`

* `context.get<Environment>()`

* `context.get<SettingsInteractor>()`

* typo

* fixed `MeteringScreenLayout`

* fixed redundant vibrations
2023-06-04 13:04:04 +02:00
Vadim
a0eb641cf3 Version bump 2023-05-21 11:52:10 +02:00
Vadim
c63b5a420d
ML-74 CameraContainerBloc crashes ()
* nullable var instead of `late`

* `.then((_) => _cameraController = null));`
2023-05-21 11:50:46 +02:00
Vadim
ba0d6d3fab Version bump 2023-05-19 11:24:02 +02:00
Vadim
8b74c4e1a4
ML-72 buildPreview() was called on a disposed CameraController ()
* added `DeinitializeEvent`

* typo
2023-05-19 11:12:10 +02:00
Vadim
00b2728453 Updated dependencies versions + lints 2023-05-19 10:47:58 +02:00
Vadim
749f2beb47 Updated kotlin version 2023-05-16 12:04:49 +02:00
Vadim
239e1004a3 Version bump 2023-05-16 11:54:00 +02:00
Vadim
ec9ba1a779
ML-58 Metering UX improvements ()
* indicate EV value error

* allow nullable ev100 in `CameraContainerBloc`

* log exif keys

* wip

* removed `UserPreferencesService` from `MeteringBloc`

* added error toast

* conflicts

* lints

* allow stop metering if `hasError`

* fixed `AnimatedDialogPicker` inability to close

* Update build.gradle
2023-05-16 11:47:53 +02:00
Vadim
5602b1ed80
ML-70 Migrate to Dart 3 + stricter lints ()
* updated pub version

* added lint

* --code=always_use_package_imports

* dart fixes

* format

* other lints
2023-05-11 15:30:18 +02:00
Vadim
19a788adcb
ML-67 ScaffoldMessenger Null check operator used on a null value () 2023-05-10 17:05:27 +02:00
Vadim
f68aea5133 Version bump 2023-05-08 17:18:59 +02:00
Vadim
4f8a415503
ML-65 [Android] Exception on mailto intent ()
* added error toast

* lints
2023-05-08 17:13:43 +02:00
Vadim
0d3641f618
ML-51 Updated abiFilters () 2023-05-08 13:45:29 +02:00
Vadim
bd675184de Version bump 2023-05-05 23:37:06 +02:00
Vadim
f1f8d74338
ML-59 ND filter value is not applied on measure () 2023-05-05 23:32:17 +02:00
Vadim
1a73cefa76 Updated Firebase versions 2023-05-05 18:18:34 +02:00
Vadim
8ded9cf98a Version bump 2023-05-05 16:32:25 +02:00
Vadim
4cabd17eb2
ML-51 Added abiFilters ()
* added abiFilters

* CD next try...
2023-05-05 15:02:12 +02:00
Vadim
2f478836ed Zip merged_native_libs
Zip merged_native_libs

Changed actions zipper

Added zip directory to CD

Removed zip directory from CD
2023-05-04 18:19:30 +02:00
Vadim
34ea034e67 Build appbundle & apk
Build appbundle & apk

Renamed github workflows
2023-05-04 18:18:21 +02:00
Vadim
7a0b563d75 Version bump 2023-05-04 15:39:35 +02:00
Vadim
2102213344
ML-54 AnimatedDialogState issues ()
* LateInitializationError: Field '_foregroundColorAnimation@1004358584'

* FlutterError: Null check operator used on a null value
2023-05-04 13:14:53 +02:00
Vadim
0583b07cb9
ML-53 Unsupported operation: Infinity or NaN toInt ()
added `isNan` & `isInfinite` checks
2023-05-04 12:49:26 +02:00
Vadim
6232ad555a
ML-51 Integrate Crashlytics ()
* added crashlytics

* added firebase_options to CD

* Version bump

* added firebase_options to CI

* timeout
2023-05-03 12:45:10 +02:00
Vadim
6944da25fa Version bump 2023-05-01 11:07:58 +02:00
Vadim
77cbd11268 [Android] Probably fixed grey screen issue 2023-05-01 11:07:07 +02:00
Vadim
d3512faa9b Fixed incorrect ISO for some films 2023-05-01 10:49:22 +02:00
Vadim
d346e706ff Moved StopTypeProvider to providers folder 2023-04-17 10:25:56 +03:00
Vadim
59b71abba0
Checked reciprocity in legacy features 2023-04-09 17:31:51 +03:00
Vadim
8a168b1424 Secrets typo 2023-04-09 13:52:57 +03:00
Vadim
0ac24e5d2c Temporarily removed firebase 2023-04-09 13:35:58 +03:00
Vadim
b936924452 Added GP resources 2023-04-08 17:27:04 +03:00
Vadim
dc2c33e494 Added google-services.json to cd 2023-04-05 22:34:06 +03:00
Vadim
efad098ea5 Version bump 2023-04-05 22:18:17 +03:00
Vadim
aaadd1ded6
ML-48 Allow users to hide fastest/shortest exposure pairs ()
* implemented `MeteringScreenLayoutProvider`

* refined topbar height difference calculation

* implemented `MeteringScreenLayoutFeaturesDialog`

* added icons to all dialogs

* save & restore `MeteringScreenLayoutConfig`

* reset film on film picker disabling

* fixed Fomapan reciprocity

* fixed dependencies

* added translations
2023-04-05 22:15:11 +03:00
Vadim
be0617a99c
ML-46 Add reciprocity failure formulas for some films ()
* added `Film` model with reciprocity formulas

* added `FeaturesConfig`

* added film picker

* unused import

* get ISO and ND from equipment profile

* udpate iso on film changed

* typo
2023-04-01 22:04:55 +03:00
Vadim
6bf059ed4d
ML-42 Implement equipment profiles creating ()
* added Equipment section placeholder

* get iso & nd values from equipment profile

* use photography values from remote repo

* removed equipment section

* wip

* moved `EquipmentProfileProvider` from iap repo

* wip

* moved equipment profiles screen from iap

* improved equipment profiles screen

* mock add/delete

* collapse on expand

* add profile with name

* show selected values count (wip)

* fixed profile update

* cleanup

* Update pubspec.yaml

* made `AnimatedDialogPicker` more generic

* switched to local `Dimens`

* fixed `MeteringTopBarShape`

* rename

* animated `EquipmentProfileContainer`

* added default equipment profile

* change equipment profile name via dialog

* fixed profile selection

* filter equipment profile update/delete

* removed `enabled` param from settings section

* non-null `EquipmentProfile`

* fixed duplicate GlobalKeys

* animated equipment list

* Update ci.yml

* fixed shutter speed anchor issue

* autofocus

* added firebase to project

* save/restore equipment profiles

* unified `SliverList`

* added SSH key to iap repo

* Update ci.yml

* ci recursive submodules

* try full url

* Revert "try full url"

This reverts commit a9b692b60e.

* restore firebase_options.dart

* changed runner to macos

* restore options earlier

* removed problematic file from analysis :)

* removed launch_app

* textoverflow

* implemented `DialogRangePicker`

* add iap repo to cd

* typo

* added    workflow_dispatch to crowdin push

* removed `equipmentProfileValuesCount` from intl

* fr & ru translations

* style

* removed iap
2023-03-30 22:24:18 +03:00
Vadim
6ffd164171
Added workflow_dispatch to crowdin push 2023-03-30 14:05:37 +03:00
Vadim
cd61204e50 Version bump 2023-03-17 22:11:03 +03:00
Vadim
6bd104660c Version bump 2023-03-17 21:47:05 +03:00
Vadim
81e01c126a Fixed android launcher icon size 2023-03-17 21:43:15 +03:00
Vadim
0fb4fc1e47 Added edge cutouts to color picker 2023-03-14 11:57:01 +01:00
Vadim
89ad717fe7 Update PRIVACY_POLICY.md 2023-02-24 10:22:56 +03:00
Vadim
57685beeea
Create PRIVACY_POLICY.md 2023-02-24 10:11:42 +03:00
Vadim
7b9f9a91c0
Upload native debug symbols to artifacts ()
* Create cd.yml

* added artifact upload

* fixed jobs sequence

* moved upload to build job

* jobs rename

* keystore

* Update cd.yml

* macos runner

* cd_dev

* Update build.gradle

* Added CD for Prod App Bundle

* Clean up

* removed redundant .apk type from appbundle artifact

* added uploading NDS to artifacts

* override version code

* override version name

* fixed gradle build path

* add version code in gradle
2023-02-23 23:05:02 +03:00
Vadim
59287d06bc Rearranged settings screen files 2023-02-19 19:19:56 +03:00
Vadim
c48f2ae373 Version bump 2023-02-19 18:18:41 +03:00
Vadim
e6338157bf
ML-5 Measure button needs loading state ()
* added

* Version bump

* Fixed indicator initial position

* Revert "Version bump"

This reverts commit 92793e013d.
2023-02-19 18:15:36 +03:00
Vadim
1c4e302103
Filter path for translations push 2023-02-19 13:46:33 +03:00
Vadim
b7639740f3
ML-5 Measure button needs loading state () 2023-02-19 13:26:14 +03:00
Vadim
333563b0f0 Version bump 2023-02-18 20:35:09 +03:00
Vadim
cbee0f350a
ML-37 Fix exposure pairs list creation ()
* integrated EV value to measure button

* fixed
2023-02-18 20:17:39 +03:00
Vadim
f8391454b6
ML-23 Implement migration mechanism for material_lightmeter users ()
* migrate existent keys

* await

* Update cd_dev.yml

* Update cd_dev.yml

* Update cd_dev.yml

* Fixed CD flavor artifact upload
2023-02-17 22:32:25 +03:00
Vadim
9945005008 Merge branch 'main' of https://github.com/vodemn/m3_lightmeter 2023-02-16 00:37:09 +03:00
Vadim
7eacc7d03b App Bundle CD fix 2023-02-16 00:36:47 +03:00
Vadim
6a05c42ee8
Build signed appbundle ()
* Create cd.yml

* added artifact upload

* fixed jobs sequence

* moved upload to build job

* jobs rename

* keystore

* Update cd.yml

* macos runner

* cd_dev

* Update build.gradle

* Added CD for Prod App Bundle

* Clean up
2023-02-16 00:25:13 +03:00
Vadim
8d1640447f
Build signed apk on tag creation ()
* Create cd.yml

* added artifact upload

* fixed jobs sequence

* moved upload to build job

* jobs rename

* keystore

* Update cd.yml

* macos runner

* cd_dev

* Update build.gradle
2023-02-16 00:16:39 +03:00
Vadim
59e440dfd7
Build apk on tag creation ()
* Create cd.yml

* added artifact upload

* fixed jobs sequence

* moved upload to build job

* jobs rename
2023-02-15 17:34:28 +03:00
Vadim
1372a75d3b
Added cd branch to cd.yml 2023-02-15 14:28:44 +03:00
Vadim
37c20c5f94
Fix flutter build 2023-02-15 14:22:35 +03:00
Vadim
fdd00a2646
Create cd.yml () 2023-02-15 13:59:10 +03:00
Vadim
0c0e4eeb3b Added French language 2023-02-14 15:30:49 +03:00
Vadim
2bee357896
Removed Crowdin pull workflow ()
* Update crowdin.yml

* added github workflows

* Update crowdin_push.yml

* Update intl_en.arb

* Update intl_en.arb

* Delete crowdin_pull.yml

* Delete crowdin_pull.yml
2023-02-12 13:28:22 +03:00
Vadim
824be6c916
Push new localization strings to Crowdin ()
* Update crowdin.yml

* added github workflows

* Update crowdin_push.yml

* Update intl_en.arb

* Update intl_en.arb
2023-02-12 13:09:55 +03:00
Vadim
a6d5032c83 Update crowdin.yml 2023-02-12 12:37:40 +03:00
Vadim
871a6dcc6c Merge branch 'main' of https://github.com/vodemn/m3_lightmeter 2023-02-12 12:37:08 +03:00
Vadim
0a2854e70f Update crowdin.yml 2023-02-12 12:35:52 +03:00
Vadim
af6b3dbedc Update Crowdin configuration file 2023-02-12 11:56:38 +03:00
Vadim
3ed8048c99 Create crowdin.yml 2023-02-12 11:54:48 +03:00
Vadim
4966c330ec Version bump 2023-02-11 22:20:45 +03:00
Vadim
485636c706
ML-28 Implement language picker ()
* added language picker

* Create intl_ru.arb

* Update README.md
2023-02-11 22:19:18 +03:00
Vadim
afdbc92ac4 [Android] Fixed system navigation bar color 2023-02-11 20:33:08 +03:00
Vadim
e4deac0fee Version bump 2023-02-11 16:01:38 +03:00
Vadim
07fd61fa1e
ML-24 Implement caffeine feature ()
* platform-specific code

* implemented caffeine flutter side

* haptics revision
2023-02-11 15:58:47 +03:00
Vadim
a183a5433e
ML-25 Revise permission handling ()
* fixed permission handling

* translations cleanup

* [Android] removed unused permissions
2023-02-11 00:49:51 +03:00
Vadim
f75afbb6c2 Merge branch 'main' of https://github.com/vodemn/m3_lightmeter 2023-02-05 17:41:09 +03:00
Vadim
186bb8f468 Fixed url launch 2023-02-05 17:41:00 +03:00
Vadim
abcdd35511
Update README.md 2023-02-05 17:34:48 +03:00
Vadim
278e95e5fb Version bump 2023-02-05 17:26:17 +03:00
Vadim
8d73a7d2e3
ML-20 Dialog pickers content jumps when selected item is out of vie ()
* fixed primary color picker overscroll

* dialog cleanup

* fixed photography value picker overscroll

* Update widget_dialog_picker_photography_value.dart
2023-02-05 17:20:36 +03:00
Vadim
9436a59094 Added camera and exposurepairs list placeholders 2023-02-05 16:56:04 +03:00
Vadim
b8c6f51bd0
ML-10 ThemeType.systemDefault doesn't reflect theme change from device settings () 2023-02-05 00:09:19 +03:00
Vadim
00e104de9b Version bump 2023-02-01 00:27:04 +03:00
Vadim
9cfffc3377
ML-18 Implement primary color picker ()
* wip

* hide `DynamicColorListTile` if unavailable

* added color animation for `AnimatedDialog`

* adjusted some colors

* sync `AnimatedDialog` insets with material

* scroll to selected color
2023-02-01 00:24:26 +03:00
Vadim
cb4e91cb0a Folders cleanup 2023-01-29 20:02:18 +03:00
Vadim
9ffb5112c1
ML-16 [Android] Implement incident light metering ()
* wip

* rename

* wip

* rename

* fixed camera screen layout

* omit camera measure on startup

* added calibration for light sensor

* save evsource

* Update widget_button_measure.dart

* fixed iOS init

* hide light sensor calibration on ios

* cleanup
2023-01-29 19:57:47 +03:00
Vadim
179008ff77 FVM fix 2023-01-26 18:33:33 +03:00
Vadim
42fe5d45bc Format & tasks 2023-01-26 18:03:48 +03:00
Vadim
130f5ff0b2
ML-14 Implement EV calibration legacy feature ()
* wip

* implemented `CalibrationDialog`

* integrated calibration to the metering bloc

* checked legacy feature
2023-01-26 12:10:23 +03:00
Vadim
31ef42c4c0
ML-12 Prepare repo to be public ()
* added source code list tile

* added settings sections

* wip

* moved theme tiles to separate folders

* added env

* added contact email

* widget folders

* dynamic colors -> dynamic color

* fixed `SettingsSection` clipBehavior

* version bump

* typo

* updated flutter to 3.7

* added style guide

* typo

* Update style_guide.md

* Update README.md

* Update README.md

* Update README.md
2023-01-25 13:08:11 +03:00
Vadim
ab0b0cefab
Checked vibration legacy feature 2023-01-22 22:47:01 +03:00
Vadim
b66d85deb5 Version bump 2023-01-22 22:41:54 +03:00
Vadim
703b29a3d5
ML-7 Exposure offset doesn't apply on app reopen () 2023-01-22 22:40:44 +03:00
Vadim
9477f80ada
ML-6 Add support for dynamic colors on A12+ ()
* added dynamic colors

* made dynamic colors enabled/disabled

* fixed tests
2023-01-22 22:30:29 +03:00
Vadim
9be413752a [Android] Made status bar transparent 2023-01-21 14:18:10 +03:00
Vadim
c7ed4d332e Added haptics
added `HapticsService`

added haptics handling

added `HapticsInteractor`
2023-01-21 14:17:44 +03:00
Vadim
9bedc6e665
Added TOC to readme 2023-01-21 00:26:31 +03:00
Vadim
cc12d32af0
Added Legacy features section to readme 2023-01-21 00:23:39 +03:00
Vadim
02a7f7d6a9 Version bump 2023-01-21 00:01:27 +03:00
Vadim
cd9ea81dd1 [Android] Fixed status bar icon brightness 2023-01-20 23:59:06 +03:00
Vadim
02e5fc582c Removed source-swap button 2023-01-20 23:39:01 +03:00
Vadim
bdf03f708f ReadingsContainer -> SizeRenderWidget 2023-01-20 23:09:17 +03:00
Vadim
5bea96669d Made TopBarShape responsive
returned `TopBarShape`

fixed `TopBarShape`
2023-01-20 23:03:55 +03:00
Vadim
5eb0869aa0 Fixed CameraPreview aspect ratio
Probably will be changed in future, is it currently relies on the `ResolutionPreset` being tied with aspect ratio
2023-01-07 13:23:54 +03:00
Vadim
56480cca0a Fixed navigation bar color
Cleanup
2023-01-07 12:22:50 +03:00
Vadim
cdd714f12c
Added app icon to README 2023-01-05 20:32:04 +03:00
Vadim
4eee9816bd
Added Backstory to README 2023-01-05 20:03:05 +03:00
Vadim
3ccabbfac4 Reverse EV compensation values 2023-01-05 19:41:37 +03:00
Vadim
abd07764fd Added zoom and exposure sliders
added `ZoomSlider` (wip)

wip

implemented horizontal slider

implemented vertical slider

integrated 2 sliders to metering screen (wip)

removed filled track

placed camera slider in the proper folder

temp fix for exposure list fonts

update exposure event

added ruler to `CameraExposureSlider`

moved slider sizes to dimens

moved `CameraZoomSlider` to the separate folder
2023-01-01 22:00:26 +03:00
Vadim
14bac950cf Fixed _models_ and _screens_ folders structure
proper folders for models

unified _screen_ folder filenames
2022-12-18 14:39:02 +03:00
499 changed files with 23657 additions and 2576 deletions
.fvmrc
.github
.gitignore
.vscode
PRIVACY_POLICY.mdREADME.mdanalysis_options.yaml
android
app
build.gradle
src
debug
dev
main
prod
profile
build.gradlegradle.properties
gradle/wrapper
settings.gradle
assets

3
.fvmrc Normal file
View file

@ -0,0 +1,3 @@
{
"flutter": "3.24.5"
}

3
.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1,3 @@
# These are supported funding model platforms
github: [vodemn]

30
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View file

@ -0,0 +1,30 @@
---
name: Bug report
about: Create a bug report to help improve the app
title: ''
labels: bug, user feedback
assignees: vodemn
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Device:**
- Device: [e.g. Pixel 6]
- OS: [e.g. Android 12]
**App version**

View file

@ -0,0 +1,17 @@
---
name: Feature request or improvement
about: Suggest an idea for this project
title: ''
labels: feature, user feedback
assignees: vodemn
---
**Describe the feature or the problem it solves**
A clear and concise description of what the problem is.
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Additional context**
Add any other context or screenshots about the feature request here.

View file

@ -0,0 +1,8 @@
export newVersion="$1"
if [[ -n "$newVersion" ]]; then
#https://stackoverflow.com/a/30214769/13167574
perl -i -pe 's/^(version:\s+)(\d+\.\d+\.\d+)(\+)(\d+)$/$1.$ENV{'newVersion'}.$3.($4+1)/e' pubspec.yaml
else
echo "argument error"
fi

14
.github/scripts/restore_from_base64.sh vendored Normal file
View file

@ -0,0 +1,14 @@
content="$1"
filename="$2"
if [[ ! -n "$content" ]]; then
echo "Provide file content"
exit 1
fi
if [[ ! -n "$filename" ]]; then
echo "Provide a path to an output file"
exit 1
fi
base64 -d <<< "$content" > "$filename"

2
.github/scripts/stub_iap.sh vendored Normal file
View file

@ -0,0 +1,2 @@
# https://unix.stackexchange.com/questions/435708/regex-multiline-pattern-and-substitution-replacement
perl -0777 -i -pe 's/( m3_lightmeter_iap:\n)( git:\n url: "https:\/\/github.com\/vodemn\/m3_lightmeter_iap"\n ref: v\d{1,2}.\d{1,2}.\d{1,2})/$1 path: iap/sg' pubspec.yaml

151
.github/workflows/build_apk.yml vendored Normal file
View file

@ -0,0 +1,151 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Build Android
run-name: Build Android (${{ inputs.binary-type == 'apk' && '.apk' || '.aab' }}) v${{ inputs.version }}
on:
workflow_call:
inputs:
version:
description: "Version"
required: true
type: string
binary-type:
description: "Binary type"
type: string
required: true
flavor:
description: "Flavor"
type: string
required: true
include-iap:
type: boolean
description: Include IAP package
default: true
stage-backend:
type: boolean
description: Use stage backend
default: true
upload-artifact:
type: boolean
description: Upload build to artifacts
default: true
workflow_dispatch:
inputs:
version:
description: "Version"
required: true
type: string
binary-type:
description: "Binary type"
type: choice
required: true
options:
- apk
- appbundle
flavor:
description: "Flavor"
type: choice
required: true
options:
- dev
- prod
default: dev
include-iap:
type: boolean
description: Include IAP package
default: true
stage-backend:
type: boolean
description: Use stage backend
default: true
upload-artifact:
type: boolean
description: Upload build to artifacts
default: true
env:
BUILD_ARGS: --release --flavor ${{ inputs.flavor }} -t lib/main_${{ inputs.flavor }}.dart
BUILD_APK_PATH: build/app/outputs/flutter-apk/app-${{ inputs.flavor }}-release.apk
BUILD_AAB_PATH: build/app/outputs/bundle/${{ inputs.flavor }}Release/app-${{ inputs.flavor }}-release.aab
RELEASE_NOTES_ARTIFACT_NAME: release_notes_en_${{ inputs.version }}
RELEASE_NOTES_PATH: "assets/release_notes"
jobs:
build-android:
name: Build ${{ inputs.binary-type == 'apk' && '.apk' || '.aab' }}
runs-on: macos-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Connect private iap package
uses: webfactory/ssh-agent@v0.8.0
if: ${{ inputs.include-iap }}
with:
ssh-private-key: ${{ secrets.M3_LIGHTMETER_IAP_KEY }}
- name: Override iap package with stub
if: ${{ !inputs.include-iap }}
run: bash ./.github/scripts/stub_iap.sh
- uses: actions/setup-java@v3
with:
distribution: "zulu"
java-version: "17"
- name: Restore Android keystore .jsk and .properties files
run: |
bash .github/scripts/restore_from_base64.sh "${{ secrets.KEYSTORE_PROPERTIES }}" "android/key.properties"
bash .github/scripts/restore_from_base64.sh "${{ secrets.KEYSTORE }}" "android/app/keystore.jks"
- name: Restore google-services.json
run: bash .github/scripts/restore_from_base64.sh "${{ secrets.GOOGLE_SERVICES_JSON_ANDROID }}" "android/app/google-services.json"
- name: Setup Firebase
run: |
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_OPTIONS }}" "lib/firebase_options.dart"
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_JSON }}" "firebase.json"
- name: Restore constants.dart
env:
CONSTANTS: ${{inputs.stage-backend && secrets.CONSTANTS_STAGE || secrets.CONSTANTS }}
run: bash .github/scripts/restore_from_base64.sh "${{ env.CONSTANTS }}" "lib/constants.dart"
- name: Increment build number & replace version number
run: bash ./.github/scripts/increment_build_number.sh ${{ github.event.inputs.version }}
- name: Download release notes
continue-on-error: true
uses: actions/download-artifact@v4
with:
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
path: ${{ env.RELEASE_NOTES_PATH }}
- name: Install Flutter
uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version: "3.24.5"
- name: Prepare flutter project
run: |
flutter --version
flutter pub get
flutter pub run intl_utils:generate
- name: Build ${{ inputs.binary-type }}
run: flutter build ${{ inputs.binary-type }} $BUILD_ARGS
- name: Upload ${{ inputs.binary-type }} to artifacts
if: ${{ inputs.upload-artifact }}
uses: actions/upload-artifact@v4
with:
name: m3_lightmeter_${{ inputs.binary-type }}
path: ${{ inputs.binary-type == 'apk' && env.BUILD_APK_PATH || env.BUILD_AAB_PATH }}

156
.github/workflows/build_ipa.yml vendored Normal file
View file

@ -0,0 +1,156 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Build iOS
run-name: Build iOS v${{ inputs.version }}
on:
workflow_call:
inputs:
version:
description: "Version"
required: true
type: string
include-iap:
type: boolean
description: Include IAP package
default: true
stage-backend:
type: boolean
description: Use stage backend
default: true
upload-artifact:
type: boolean
description: Upload build to artifacts
default: true
workflow_dispatch:
inputs:
version:
description: "Version"
required: true
type: string
include-iap:
type: boolean
description: Include IAP package
default: true
stage-backend:
type: boolean
description: Use stage backend
default: true
upload-artifact:
type: boolean
description: Upload build to artifacts
default: true
env:
FLAVOR: "prod"
RELEASE_NOTES_ARTIFACT_NAME: release_notes_en_${{ inputs.version }}
RELEASE_NOTES_PATH: "assets/release_notes"
jobs:
build:
name: Build .ipa
runs-on: macos-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Connect private iap package
uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.M3_LIGHTMETER_IAP_KEY }}
- name: Install the Apple certificate and provisioning profile
env:
APP_STORE_P12: ${{ secrets.APP_STORE_P12 }}
APP_STORE_P12_PASSWORD: ${{ secrets.APP_STORE_P12_PASSWORD }}
APP_STORE_PROVISION_PROD: ${{ secrets.APP_STORE_PROVISION_PROD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
PROVISION_PATH=$RUNNER_TEMP/build_provision.mobileprovision
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# import certificate and provisioning profile from secrets
echo -n "$APP_STORE_P12" | base64 --decode -o $CERTIFICATE_PATH
echo -n "$APP_STORE_PROVISION_PROD" | base64 --decode -o $PROVISION_PATH
# create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# import certificate to keychain
security import $CERTIFICATE_PATH -P "$APP_STORE_P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
# apply provisioning profile
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PROVISION_PATH ~/Library/MobileDevice/Provisioning\ Profiles
- name: Restore GoogleService-Info.plist
run: bash .github/scripts/restore_from_base64.sh "${{ secrets.GOOGLE_SERVICES_JSON_IOS }}" "ios/Runner/GoogleService-Info.plist"
- name: Restore ExportOptions.plist
run: bash .github/scripts/restore_from_base64.sh "${{ secrets.APP_STORE_EXPORT_OPTIONS }}" "ios/Runner/ExportOptions.plist"
- name: Setup Firebase
run: |
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_APP_ID_FILE }}" "ios/firebase_app_id_file.json"
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_OPTIONS }}" "lib/firebase_options.dart"
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_JSON }}" "firebase.json"
- name: Restore constants.dart
env:
CONSTANTS: ${{inputs.stage-backend && secrets.CONSTANTS_STAGE || secrets.CONSTANTS }}
run: bash .github/scripts/restore_from_base64.sh "${{ env.CONSTANTS }}" "lib/constants.dart"
- name: Increment build number & replace version number
run: bash ./.github/scripts/increment_build_number.sh ${{ github.event.inputs.version }}
- name: Download release notes
continue-on-error: true
uses: actions/download-artifact@v4
with:
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
path: ${{ env.RELEASE_NOTES_PATH }}
- name: Install Flutter
uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version: "3.24.5"
- name: Prepare flutter project
run: |
flutter --version
flutter pub get
flutter pub run intl_utils:generate
dart pub global activate flutterfire_cli
- name: Build .ipa
run: |
flutter build ipa \
--release \
--flavor $FLAVOR \
--target lib/main_$FLAVOR.dart \
--export-options-plist=ios/Runner/ExportOptions.plist
- name: Upload artifact
if: ${{ inputs.upload-artifact }}
uses: actions/upload-artifact@v4
with:
name: m3_lightmeter_ipa
path: build/ios/ipa/lightmeter.ipa
- name: Clean up keychain and provisioning profile
if: ${{ always() }}
run: |
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
rm ~/Library/MobileDevice/Provisioning\ Profiles/build_provision.mobileprovision

View file

@ -1,37 +0,0 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Dart
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: subosito/flutter-action@v2
with:
channel: "stable"
- name: Check flutter version
run: flutter --version
- name: Install dependencies
run: flutter pub get
- name: Generate intl
run: flutter pub run intl_utils:generate
- name: Analyze project source
run: flutter analyze
- name: Run tests
run: flutter test

240
.github/workflows/create_release.yml vendored Normal file
View file

@ -0,0 +1,240 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow uses perl regex. For better syntaxis understading see these docs:
# https://perldoc.perl.org/perlrequick#Search-and-replace
# https://perldoc.perl.org/perlre#Other-Modifiers
name: Create new release
run-name: Release v${{ inputs.version }}${{ inputs.release-track == 'beta' && '-Beta' || '' }}
on:
workflow_dispatch:
inputs:
version:
description: "Version"
required: true
type: string
release-notes:
description: "Release notes"
required: true
type: string
run-integration-tests:
description: "Run integration tests"
required: true
type: boolean
default: true
deploy-ios:
description: "Publish to App Store"
required: true
type: boolean
default: true
deploy-android:
description: "Publish to Google Play"
required: true
type: boolean
default: true
release-track:
description: "Release track"
type: choice
required: true
options:
- production
- beta
default: production
env:
RELEASE_NOTES_ARTIFACT_NAME: release_notes_en_${{ inputs.version }}
RELEASE_NOTES_FILE: release_notes_en_${{ inputs.version }}.md
RELEASE_NOTES_PATH: "assets/release_notes"
jobs:
run-integration-tests:
name: Run integration tests
if: ${{ inputs.run-integration-tests }}
uses: ./.github/workflows/run_integration_tests.yml
secrets: inherit
generate-release-notes:
name: Generate release notes
needs: [run-integration-tests]
if: ${{ always() && !failure() && !cancelled() }}
runs-on: ubuntu-latest
steps:
- name: Generate release notes
run: |
echo ${{ inputs.release-notes }} > ${{ env.RELEASE_NOTES_FILE }}
perl -i -pe 's/\s{1}(-{1})/\n$1/g' ${{ env.RELEASE_NOTES_FILE }}
- name: Upload merged_native_libs.zip to artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
path: ${{ env.RELEASE_NOTES_FILE }}
build-android:
name: Build Android
needs: [generate-release-notes]
if: ${{ always() && !failure() && !cancelled() && inputs.deploy-android }}
strategy:
matrix:
binary-type: [apk, appbundle]
uses: ./.github/workflows/build_apk.yml
secrets: inherit
with:
binary-type: ${{ matrix.binary-type }}
flavor: prod
upload-artifact: true
stage-backend: false
version: ${{ inputs.version }}
build-ios:
name: Build iOS
needs: [generate-release-notes]
if: ${{ always() && !failure() && !cancelled() && inputs.deploy-ios }}
uses: ./.github/workflows/build_ipa.yml
secrets: inherit
with:
upload-artifact: true
stage-backend: false
version: ${{ inputs.version }}
create-github-release:
name: Create Github release
needs: [build-android, build-ios]
if: ${{ always() && !cancelled() && inputs.deploy-android}}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Download apk
uses: actions/download-artifact@v4
with:
name: m3_lightmeter_apk
- name: Download release notes
uses: actions/download-artifact@v4
with:
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
path: ${{ env.RELEASE_NOTES_PATH }}
- name: Increment build number & replace version number
run: bash ./.github/scripts/increment_build_number.sh ${{ github.event.inputs.version }}
- name: Commit changes
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add --all -- ":!app-prod-release.apk"
git commit -m "Release v${{ inputs.version }}"
- name: Push to main
uses: CasperWA/push-protected@v2
with:
token: ${{ secrets.PUSH_TO_MAIN_TOKEN }}
branch: ${{ github.ref_name }}
unprotect_reviews: true
- name: Rename apk
run: mv app-prod-release.apk m3_lightmeter.apk
- uses: ncipollo/release-action@v1.12.0
with:
artifacts: "m3_lightmeter.apk"
skipIfReleaseExists: true
prerelease: ${{ inputs.release-track == 'beta' }}
tag: "v${{ github.event.inputs.version }}${{ inputs.release-track == 'beta' && '-beta' || '' }}"
bodyFile: "${{ env.RELEASE_NOTES_PATH }}/${{ env.RELEASE_NOTES_FILE }}"
create-google-play-release:
name: Create Google Play release
needs: [build-android, build-ios]
if: ${{ always() && !failure() && !cancelled() && inputs.deploy-android }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Download app bundle
uses: actions/download-artifact@v4
with:
name: m3_lightmeter_appbundle
- name: Extract & zip merged_native_libs
run: |
unzip app-prod-release.aab
(cd base/lib && zip -r "$OLDPWD/merged_native_libs.zip" .)
- name: Download release notes
uses: actions/download-artifact@v4
with:
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
- name: Move release notes to a folder
run: |
mv ${{ env.RELEASE_NOTES_FILE }} whatsnew-en-US
mkdir whatsnew
mv whatsnew-en-US whatsnew
# https://unix.stackexchange.com/questions/13466/can-grep-output-only-specified-groupings-that-match'
# https://stackoverflow.com/questions/74353311/github-workflow-unable-to-process-file-command-env-successfully
- name: Create Google Play release name
id: release-name
run: |
RELEASE_NAME=$(echo "$(cat pubspec.yaml)" | sed -n -r "s/^version:\s{1}(.*)[+](.*)$/700\2 (\1)/p")
echo "release_name=$RELEASE_NAME" >> $GITHUB_ENV
- name: Create Google Play release
id: create-google-play-release-step
uses: r0adkll/upload-google-play@v1.1.1
with:
serviceAccountJsonPlainText: ${{ secrets.GH_ACTIONS_SERVICE_ACCOUNT_JSON }}
packageName: com.vodemn.lightmeter
releaseFiles: app-prod-release.aab
releaseName: ${{ env.release_name }}
track: ${{ inputs.release-track }}
status: completed
debugSymbols: merged_native_libs.zip
whatsNewDirectory: whatsnew
upload-to-app-store:
name: Upload to App Store
needs: [build-android, build-ios]
if: ${{ always() && !failure() && !cancelled() && inputs.deploy-ios }}
runs-on: macos-13
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Download ipa
uses: actions/download-artifact@v4
with:
name: m3_lightmeter_ipa
- name: Upload app to TestFlight
run: xcrun altool --upload-app -f lightmeter.ipa -t ios -u ${{ secrets.APP_STORE_USERNAME }} -p ${{ secrets.APP_STORE_PASSWORD }}
cleanup:
name: Cleanup
if: ${{ always() }}
needs:
[create-github-release, create-google-play-release, upload-to-app-store]
runs-on: ubuntu-latest
steps:
- name: Delete release artifacts
uses: geekyeggo/delete-artifact@v2
with:
failOnError: false
name: |
m3_lightmeter_apk
m3_lightmeter_appbundle
m3_lightmeter_ipa
${{ env.RELEASE_NOTES_ARTIFACT_NAME }}

33
.github/workflows/crowdin_push.yml vendored Normal file
View file

@ -0,0 +1,33 @@
name: Crowdin push
on:
workflow_dispatch:
push:
paths:
- lib/l10n/**
branches:
- main
- crowdin
concurrency:
group: ${{ github.workflow }}
permissions:
contents: read
env:
REPO_TOKEN: ${{ secrets.REPO_TOKEN }}
CROWDIN_PROJECT_ID: 567473
CROWDIN_TOKEN: ${{ secrets.CROWDIN_TOKEN }}
jobs:
upload-files:
runs-on: ubuntu-latest
steps:
- name: Checkout main branch
uses: actions/checkout@v3
- name: Upload
uses: crowdin/github-action@1.5.0
with:
crowdin_branch_name: main
upload_sources: true
upload_sources_args: "--delete-obsolete"
upload_translations: true
import_eq_suggestions: true
auto_approve_imported: false
add_crowdin_branch: main

120
.github/workflows/pr_check.yml vendored Normal file
View file

@ -0,0 +1,120 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: PR check
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
jobs:
analyze-and-test:
name: Analyze & test
runs-on: macos-14
timeout-minutes: 10
env:
EMPTY_CONSTANTS: Y29uc3QgU3RyaW5nIGlhcFNlcnZlclVybCA9ICcnOwpjb25zdCBTdHJpbmcgaXNzdWVzUmVwb3J0VXJsID0gJyc7CmNvbnN0IFN0cmluZyBzb3VyY2VDb2RlVXJsID0gJyc7CmNvbnN0IFN0cmluZyBjb250YWN0RW1haWwgPSAnJzsK
EMPTY_FIREBASE_OPTIONS: Ly8gaWdub3JlX2Zvcl9maWxlOiB0eXBlPWxpbnQKaW1wb3J0ICdwYWNrYWdlOmZpcmViYXNlX2NvcmUvZmlyZWJhc2VfY29yZS5kYXJ0JyBzaG93IEZpcmViYXNlT3B0aW9uczsKY2xhc3MgRGVmYXVsdEZpcmViYXNlT3B0aW9ucyB7c3RhdGljIEZpcmViYXNlT3B0aW9ucyBnZXQgY3VycmVudFBsYXRmb3JtID0+RmlyZWJhc2VPcHRpb25zKGFwaUtleTogJycsIGFwcElkOiAnJywgbWVzc2FnaW5nU2VuZGVySWQ6ICcnLCBwcm9qZWN0SWQ6ICcnKTt9Cg==
steps:
- uses: 8BitJonny/gh-get-current-pr@2.2.0
id: PR
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Connect private iap package
uses: webfactory/ssh-agent@v0.8.0
id: fetch-iap
if: steps.PR.outputs.number == 'null' || github.event.pull_request.head.repo.full_name == github.repository
with:
ssh-private-key: ${{ secrets.M3_LIGHTMETER_IAP_KEY }}
- name: Override iap package with stub
id: override-iap
if: steps.fetch-iap.conclusion != 'success'
run: bash ./.github/scripts/stub_iap.sh
- name: Restore secrets
env:
CONSTANTS: ${{ steps.fetch-iap.conclusion == 'success' && secrets.CONSTANTS || env.EMPTY_CONSTANTS }}
FIREBASE_OPTIONS: ${{ steps.fetch-iap.conclusion == 'success' && secrets.FIREBASE_OPTIONS || env.EMPTY_FIREBASE_OPTIONS }}
run: |
bash .github/scripts/restore_from_base64.sh "${{ env.CONSTANTS }}" "lib/constants.dart"
bash .github/scripts/restore_from_base64.sh "${{ env.FIREBASE_OPTIONS }}" "lib/firebase_options.dart"
- uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version: "3.24.5"
- name: Prepare flutter project
run: |
flutter --version
flutter pub get
flutter pub run intl_utils:generate
- name: Analyze project source
run: flutter analyze lib --fatal-infos
- name: Run tests
run: |
defaults -currentHost write -g AppleFontSmoothing -int 0
flutter test --dart-define cameraStubImage=assets/camera_stub_image.jpg
- name: Analyze project source with stub
if: steps.override-iap.conclusion != 'success'
run: |
bash ./.github/scripts/stub_iap.sh
flutter pub get
flutter analyze lib --fatal-infos
platform-changes:
name: Checks for platform changes
runs-on: ubuntu-latest
outputs:
android-changed: ${{ steps.platform-changes.outputs.android-changed }}
ios-changed: ${{ steps.platform-changes.outputs.ios-changed }}
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- id: platform-changes
uses: dorny/paths-filter@v2
with:
filters: |
android-changed:
- 'android/**'
- 'pubspec.yaml'
ios-changed:
- 'ios/**'
- 'pubspec.yaml'
build-android:
name: Build Android
needs: platform-changes
if: needs.platform-changes.outputs.android-changed == 'true'
uses: ./.github/workflows/build_apk.yml
secrets: inherit
with:
binary-type: apk
flavor: prod
upload-artifact: false
stage-backend: false
version: "1.0.0"
build-ios:
name: Build iOS
needs: platform-changes
if: needs.platform-changes.outputs.ios-changed == 'true'
uses: ./.github/workflows/build_ipa.yml
secrets: inherit
with:
upload-artifact: false
stage-backend: false
version: "1.0.0"

View file

@ -0,0 +1,58 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Run integration tests
on:
workflow_dispatch:
workflow_call:
jobs:
run-integration-tests:
name: Run integration tests
timeout-minutes: 90
runs-on: macos-13
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Override iap package with stub
run: bash ./.github/scripts/stub_iap.sh
- name: Restore secrets
run: |
bash .github/scripts/restore_from_base64.sh "${{ secrets.CONSTANTS }}" "lib/constants.dart"
bash .github/scripts/restore_from_base64.sh "${{ secrets.GOOGLE_SERVICES_JSON_IOS }}" "ios/Runner/GoogleService-Info.plist"
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_APP_ID_FILE }}" "ios/firebase_app_id_file.json"
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_OPTIONS }}" "lib/firebase_options.dart"
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_JSON }}" "firebase.json"
- uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version: "3.24.5"
- name: Prepare app
run: |
flutter --version
flutter pub get
flutter pub run intl_utils:generate
flutter analyze lib --fatal-infos
dart pub global activate flutterfire_cli
- name: Launch iOS simulator
uses: futureware-tech/simulator-action@v3
with:
model: "iPhone 15 Pro"
- name: Run tests
run: |
flutter drive \
--target=integration_test/run_all_tests.dart \
--driver=test_driver/integration_driver.dart \
--flavor=dev \
--no-dds \
--dart-define cameraStubImage=assets/camera_stub_image.jpg

21
.gitignore vendored
View file

@ -5,9 +5,11 @@
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/
# IntelliJ related
@ -48,5 +50,20 @@ app.*.map.json
/ios/build/
/ios/Runner.xcodeproj/project.pbxproj
pubspec.lock
/ios/Podfile.lock
/ios/Podfile.lock
.fvm/
.jks
keystore.properties
android/app/google-services.json
ios/firebase_app_id_file.json
ios/Runner/GoogleService-Info.plist
lib/firebase_options.dart
lib/constants.dart
coverage/
test/coverage_helper_test.dart
**/failures/*.png
screenshots/generated/raw/
firebase.json

52
.vscode/launch.json vendored
View file

@ -5,34 +5,74 @@
"version": "0.2.0",
"configurations": [
{
"name": "dev",
"name": "dev-debug",
"request": "launch",
"type": "dart",
"flutterMode": "debug",
"args": [
"--flavor",
"dev",
],
"program": "${workspaceFolder}/lib/main.dart",
"program": "${workspaceFolder}/lib/main_dev.dart",
},
{
"name": "dev (mock)",
"name": "dev-profile",
"request": "launch",
"type": "dart",
"flutterMode": "profile",
"args": [
"--flavor",
"dev",
],
"program": "${workspaceFolder}/lib/main_mock.dart",
"program": "${workspaceFolder}/lib/main_dev.dart",
},
{
"name": "prod",
"name": "prod-debug",
"request": "launch",
"type": "dart",
"flutterMode": "debug",
"args": [
"--flavor",
"prod",
],
"program": "${workspaceFolder}/lib/main.dart",
"program": "${workspaceFolder}/lib/main_prod.dart",
},
{
"name": "prod-profile",
"request": "launch",
"type": "dart",
"flutterMode": "profile",
"args": [
"--flavor",
"prod",
],
"program": "${workspaceFolder}/lib/main_prod.dart",
},
{
"name": "dev-simulator",
"request": "launch",
"type": "dart",
"flutterMode": "debug",
"args": [
"--flavor",
"dev",
"--dart-define",
"cameraStubImage=assets/camera_stub_image.jpg"
],
"program": "${workspaceFolder}/lib/main_dev.dart",
},
{
"name": "integration-test",
"request": "launch",
"type": "dart",
"flutterMode": "debug",
"args": [
"--flavor",
"dev",
"--dart-define",
"cameraStubImage=assets/camera_stub_image.jpg"
],
"program": "${workspaceFolder}/integration_test/run_all_tests.dart",
},
],
}

25
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,25 @@
{
"task.slowProviderWarning": true,
"dart.flutterSdkPath": ".fvm/flutter_sdk",
"search.exclude": {
"**/.fvm": true
},
"files.watcherExclude": {
"**/.fvm": true
},
"dart.lineLength": 120,
"[dart]": {
"editor.rulers": [
120
],
"editor.selectionHighlight": true,
"editor.suggest.snippetsPreventQuickSuggestions": false,
"editor.suggestSelection": "first",
"editor.tabCompletion": "onlySnippets",
"editor.wordBasedSuggestions": "off"
},
"dart.doNotFormat": [
"**/generated/**",
"lib/data/**"
]
}

47
.vscode/tasks.json vendored Normal file
View file

@ -0,0 +1,47 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "fvm_build_android_dev",
"type": "shell",
"command": ".fvm/flutter_sdk/bin/flutter",
"args": [
"build",
"apk",
"--flavor",
"dev",
"--release",
"-t",
"lib/main_dev.dart",
],
},
{
"label": "fvm_build_android_prod",
"type": "shell",
"command": ".fvm/flutter_sdk/bin/flutter",
"args": [
"build",
"apk",
"--flavor",
"prod",
"--release",
"-t",
"lib/main_prod.dart",
],
},
{
"label": "fvm_build_appbundle",
"type": "shell",
"command": ".fvm/flutter_sdk/bin/flutter",
"args": [
"build",
"appbundle",
"--flavor",
"prod",
"--release",
"-t",
"lib/main_prod.dart",
],
},
]
}

27
PRIVACY_POLICY.md Normal file
View file

@ -0,0 +1,27 @@
**Privacy Policy**
I, Vadim Turko, built the Material Lightmeter app as a Free app. This app is provided at no cost and is intended for use as is.
**Information Collection and Use**
When using this app no personal data is collected. All settings such as theme, calibration values and other preferences are stored only on your device and never sent over the Internet.
**Log Data**
I want to inform you that whenever you use Lightmeter app, in a case of an error in the app I collect data and information (through third-party products) on your phone called Log Data. This Log Data may include information such as your device name, operating system version, the configuration of the app, the time and date of your use of the App, and other statistics.
**Links to Other Sites**
This app contains links to other sites. If you click on a third-party link, you will be directed to that site. I have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services.
* [GitHub](https://docs.github.com/en/site-policy/privacy-policies/github-privacy-statement)
**Changes to This Privacy Policy**
I may update our Privacy Policy from time to time. Thus, you are advised to review this page periodically for any changes. I will notify you of any changes by posting the new Privacy Policy on this page.
This policy is effective as of 2024-01-04
**Contact Us**
If you have any questions or suggestions about my Privacy Policy, do not hesitate to contact me at contact.vodemn@gmail.com.

View file

@ -1 +1,83 @@
# material_lightmeter
<img src="resources/social_preview.png" width="100%" />
![](https://github.com/vodemn/m3_lightmeter/actions/workflows/pr_check.yml/badge.svg)
![](https://github.com/vodemn/m3_lightmeter/actions/workflows/create_release.yml/badge.svg)
# Table of contents
- [Table of contents](#table-of-contents)
- [Backstory](#backstory)
- [Screenshots](#screenshots)
- [Development](#development)
- [Support](#support)
- [iOS Limitations](#ios-limitations)
# Backstory
Some time ago I've started developing the [Material Lightmeter](https://play.google.com/store/apps/details?id=com.vodemn.lightmeter&hl=en&gl=US) app. Unfortunately, the last update of this app was almost a year prior to creation of this repo. So after reading some positive review on Google Play saying that "this is an excellent app, too bad it is no longer updated", I've decided to make an update and also make this app open source. Maybe someone sometime will decide to contribute to this project.
But as the existing repo contained some sensitive data, that I've pushed due to lack of experience, I had to make a new one. And if creating a new repo, why not rewrite the app from scratch?
Without further delay behold my new Lightmeter app inspired by Material You (a.k.a. M3)
# Screenshots
<p float="center">
<img src="screenshots/generated/ios/iphone65inch/light_metering-reflected.png" width="18.8%" />
<img src="screenshots/generated/ios/iphone65inch/light_equipment-profiles.png" width="18.8%" />
<img src="screenshots/generated/ios/iphone65inch/light_settings.png" width="18.8%" />
<img src="screenshots/generated/ios/iphone65inch/light_timer.png" width="18.8%" />
<img src="screenshots/generated/ios/iphone65inch/dark_metering-reflected.png" width="18.8%" />
</p>
# Development
### 1. Install Flutter
To build this app you need to install Flutter 3.24.5 stable. [How to install](https://docs.flutter.dev/get-started/install).
### 2. Project setup
#### Restore git-ignored files:
For macOS you can just run the following script:
```console
sh scripts/setup_fork.sh
```
Or create the files manually using the contents from the script.
#### Get dependencies
> 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:
```console
flutter pub get
flutter pub run intl_utils:generate
```
### 3. Build
- Checkout [Build .apk](.github/workflows/build_apk.yml) workflow for Android
- Checkout [Build .ipa](.github/workflows/build_ipa.yml) workflow for iOS
# Support
To report a bug or suggest a new feature open a new [issue](https://github.com/vodemn/m3_lightmeter/issues). To contribute to the project feel free to open a Pull Request, but you need to follow this [style guide](doc/style_guide.md).
In case you have any other questions please contact me via [email](mailto:contact.vodemn@gmail.com?subject="Lightmeter").
# iOS Limitations
A list of features, that Android version of the app has and that iOS does not.
## Incident light metering
Apple does not provide API for reading Lux stream form the ambient light sensor. Lux can be calculated based on front camera image stream, but this would be a reflected light. So there is no way incident light metering can be implemented on iOS.
## Volume buttons action
This can be [implemented](https://stackoverflow.com/questions/70161271/ios-override-hardware-volume-buttons-same-as-zello) but the app will be rejected due to [2.5.9](https://developer.apple.com/app-store/review/guidelines/#software-requirements)

View file

@ -1 +1,10 @@
include: package:flutter_lints/flutter.yaml
include: package:lint/strict.yaml
linter:
rules:
use_setters_to_change_properties: false
analyzer:
exclude:
- "**/generated/**"
- lib/firebase_options.dart

View file

@ -1,3 +1,11 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id "dev.flutter.flutter-gradle-plugin"
id "com.google.gms.google-services"
id "com.google.firebase.crashlytics"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
@ -6,11 +14,6 @@ if (localPropertiesFile.exists()) {
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
@ -21,13 +24,15 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
compileSdkVersion 33
ndkVersion flutter.ndkVersion
compileSdkVersion 35
ndkVersion "27.0.12077973"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
@ -35,7 +40,7 @@ android {
}
kotlinOptions {
jvmTarget = '1.8'
jvmTarget = JavaVersion.VERSION_1_8
}
sourceSets {
@ -43,25 +48,57 @@ android {
}
defaultConfig {
minSdkVersion 21
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
minSdkVersion 23
targetSdkVersion 34
ndk {
debugSymbolLevel 'FULL'
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
/// legacy material-lightmeter ap stopped updating after 60022
/// 7xxxx means that it is a new app
versionCode 70000 + flutterVersionCode.toInteger()
versionName flutterVersionName
}
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}
flavorDimensions "app"
productFlavors {
dev {
applicationId "com.vodemn.lightmeter.dev"
resValue "string", "app_name", "Lightmeter (DEV)"
dimension "app"
signingConfig signingConfigs.debug
signingConfig signingConfigs.release
applicationIdSuffix ".dev"
}
prod {
applicationId "com.vodemn.lightmeter"
resValue "string", "app_name", "Lightmeter"
dimension "app"
signingConfig signingConfigs.debug
signingConfig signingConfigs.release
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
signingConfig signingConfigs.release
minifyEnabled true
shrinkResources true
ndk {
debugSymbolLevel 'FULL'
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
}
namespace 'com.vodemn.lightmeter'
}
flutter {
@ -69,5 +106,6 @@ flutter {
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "com.android.billingclient:billing-ktx:6.0.0"
implementation "com.google.firebase:firebase-analytics:17.4.1"
}

View file

@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.vodemn.lightmeter">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.

Binary file not shown.

After

(image error) Size: 24 KiB

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

After

(image error) Size: 2 KiB

Binary file not shown.

After

(image error) Size: 2.8 KiB

Binary file not shown.

After

(image error) Size: 3.7 KiB

Binary file not shown.

After

(image error) Size: 1.3 KiB

Binary file not shown.

After

(image error) Size: 1.7 KiB

Binary file not shown.

After

(image error) Size: 2.1 KiB

Binary file not shown.

After

(image error) Size: 2.8 KiB

Binary file not shown.

After

(image error) Size: 4.2 KiB

Binary file not shown.

After

(image error) Size: 5.4 KiB

Binary file not shown.

After

(image error) Size: 4.4 KiB

Binary file not shown.

After

(image error) Size: 7.2 KiB

Binary file not shown.

After

(image error) Size: 8.6 KiB

Binary file not shown.

After

(image error) Size: 6.2 KiB

Binary file not shown.

After

(image error) Size: 11 KiB

Binary file not shown.

After

(image error) Size: 12 KiB

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#212121</color>
</resources>

View file

@ -1,9 +1,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.vodemn.lightmeter">
<application
android:label="Lightmeter"
xmlns:tools="http://schemas.android.com/tools">
<application
android:label="@string/app_name"
android:name="${applicationName}"
android:icon="@mipmap/launcher_icon">
android:icon="@mipmap/ic_launcher"
android:allowBackup="false">
<activity
android:name=".MainActivity"
android:exported="true"
@ -12,18 +14,19 @@
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:screenOrientation="portrait"
android:dataExtractionRules="@xml/data_extraction_rules"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
@ -33,6 +36,18 @@
android:value="2" />
</application>
<queries>
<intent>
<action android:name="android.intent.action.SEND" />
<data android:scheme="mailto" />
<category android:name="android.intent.category.DEFAULT" />
</intent>
</queries>
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="true" />
</manifest>
<uses-permission android:name="android.permission.RECORD_AUDIO" tools:node="remove" />
<uses-permission android:name="android.permission.MICROPHONE" tools:node="remove" />
<uses-feature android:name="android.hardware.microphone" android:required="false" />
</manifest>

Binary file not shown.

After

(image error) Size: 18 KiB

View file

@ -1,6 +1,95 @@
package com.vodemn.lightmeter
import android.os.Bundle
import android.view.KeyEvent
import android.view.WindowManager
import androidx.core.view.WindowCompat
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.EventChannel.EventSink
import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterActivity() {
class MainActivity : FlutterActivity() {
private lateinit var keepScreenOnChannel: MethodChannel
private lateinit var volumeHandlingChannel: MethodChannel
private lateinit var volumeEventChannel: EventChannel
private var volumeEventsEmitter: EventSink? = null
private var handleVolume = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
}
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
keepScreenOnChannel = MethodChannel(
flutterEngine.dartExecutor.binaryMessenger,
"com.vodemn.lightmeter/keepScreenOn"
)
keepScreenOnChannel.setMethodCallHandler { call, result ->
when (call.method) {
"isKeepScreenOn" -> result.success((window.attributes.flags and WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) != 0)
"setKeepScreenOn" -> {
if (call.arguments !is Boolean) {
result.error("invalid args", "Argument should be of type Bool for 'setKeepScreenOn' call", null)
} else {
if (call.arguments as Boolean) window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
else window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
result.success(true)
}
}
else -> result.notImplemented()
}
}
volumeHandlingChannel = MethodChannel(
flutterEngine.dartExecutor.binaryMessenger,
"com.vodemn.lightmeter/volumeHandling"
)
volumeHandlingChannel.setMethodCallHandler { call, result ->
when (call.method) {
"setVolumeHandling" -> {
handleVolume = call.arguments as Boolean
result.success(handleVolume)
}
else -> result.notImplemented()
}
}
volumeEventChannel = EventChannel(
flutterEngine.dartExecutor.binaryMessenger,
"com.vodemn.lightmeter/volumeEvents"
)
volumeEventChannel.setStreamHandler(object : EventChannel.StreamHandler {
override fun onListen(listener: Any?, eventSink: EventSink) {
volumeEventsEmitter = eventSink
}
override fun onCancel(listener: Any?) {
volumeEventsEmitter = null
}
})
}
override fun onDestroy() {
keepScreenOnChannel.setMethodCallHandler(null)
volumeHandlingChannel.setMethodCallHandler(null)
volumeEventChannel.setStreamHandler(null)
super.onDestroy()
}
override fun onKeyDown(code: Int, event: KeyEvent): Boolean {
return when (val keyCode: Int = event.keyCode) {
KeyEvent.KEYCODE_VOLUME_UP, KeyEvent.KEYCODE_VOLUME_DOWN -> {
if (handleVolume) {
volumeEventsEmitter?.success(keyCode)
true
} else {
super.onKeyDown(code, event)
}
}
else -> super.onKeyDown(code, event)
}
}
}

Binary file not shown.

After

(image error) Size: 4.4 KiB

Binary file not shown.

After

(image error) Size: 3.3 KiB

Binary file not shown.

After

(image error) Size: 11 KiB

Binary file not shown.

After

(image error) Size: 20 KiB

Binary file not shown.

After

(image error) Size: 27 KiB

Binary file not shown.

Before

(image error) Size: 544 B

Binary file not shown.

Before

(image error) Size: 2.4 KiB

Binary file not shown.

Before

(image error) Size: 442 B

Binary file not shown.

Before

(image error) Size: 1.4 KiB

Binary file not shown.

Before

(image error) Size: 721 B

Binary file not shown.

Before

(image error) Size: 2.6 KiB

Binary file not shown.

Before

(image error) Size: 1 KiB

Binary file not shown.

Before

(image error) Size: 4.1 KiB

Binary file not shown.

Before

(image error) Size: 1.4 KiB

Binary file not shown.

Before

(image error) Size: 4.4 KiB

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#212121</color>
</resources>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>
<cloud-backup>
<exclude domain="sharedpref" path="FlutterSecureStorage"/>
<exclude domain="sharedpref" path="FlutterSecureKeyStorage"/>
</cloud-backup>
<device-transfer>
<exclude domain="sharedpref" path="FlutterSecureStorage"/>
<exclude domain="sharedpref" path="FlutterSecureKeyStorage"/>
</device-transfer>
</data-extraction-rules>

Binary file not shown.

After

(image error) Size: 15 KiB

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

After

(image error) Size: 1.4 KiB

Binary file not shown.

After

(image error) Size: 1.8 KiB

Binary file not shown.

After

(image error) Size: 3 KiB

Binary file not shown.

After

(image error) Size: 787 B

Binary file not shown.

After

(image error) Size: 1.1 KiB

Binary file not shown.

After

(image error) Size: 1.6 KiB

Binary file not shown.

After

(image error) Size: 2 KiB

Binary file not shown.

After

(image error) Size: 2.8 KiB

Binary file not shown.

After

(image error) Size: 4.3 KiB

Binary file not shown.

After

(image error) Size: 3.1 KiB

Binary file not shown.

After

(image error) Size: 4.7 KiB

Binary file not shown.

After

(image error) Size: 6.8 KiB

Binary file not shown.

After

(image error) Size: 4.4 KiB

Binary file not shown.

After

(image error) Size: 7.1 KiB

Binary file not shown.

After

(image error) Size: 10 KiB

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#212121</color>
</resources>

View file

@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.vodemn.lightmeter">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.

View file

@ -1,16 +1,3 @@
buildscript {
ext.kotlin_version = '1.6.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
@ -26,6 +13,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}

View file

@ -1,3 +1,6 @@
org.gradle.jvmargs=-Xmx1536M
org.gradle.jvmargs=-Xmx2048M
android.useAndroidX=true
android.enableJetifier=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false

View file

@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip

View file

@ -1,11 +1,27 @@
include ':app'
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}()
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version '8.7.3' apply false
id "org.jetbrains.kotlin.android" version "1.8.21" apply false
id "com.google.gms.google-services" version "4.4.0" apply false
id "com.google.firebase.crashlytics" version "2.9.9" apply false
}
include ":app"

11
assets/README.md Normal file
View file

@ -0,0 +1,11 @@
# Assets
## Launcher icons
### Android
Resources for Android are generated in Android Studio from the 512x512 source image as described in this [guide](https://developer.android.com/studio/write/create-app-icons).
### iOS
Resources for iOS are generated in XCode from the 1024x1024 source image as described in this [guide](https://developer.apple.com/documentation/xcode/configuring-your-app-icon).

Binary file not shown.

After

(image error) Size: 899 KiB

Binary file not shown.

Before

(image error) Size: 3.9 KiB

Binary file not shown.

After

(image error) Size: 21 KiB

Binary file not shown.

After

(image error) Size: 14 KiB

Binary file not shown.

After

(image error) Size: 14 KiB

Binary file not shown.

After

(image error) Size: 6 KiB

Binary file not shown.

Before

(image error) Size: 2.2 KiB

View file

@ -0,0 +1,4 @@
- [Pro] Added a timer for shooting long exposures without leaving the app, just tap the necessary shutter speed in the list.
- Long exposure values are no longer limited by 1" and are generated to match the list of aperture values.
- Refined the app's color palette & unified icons across the app.
- Added release notes dialog.

View file

@ -0,0 +1,3 @@
- Added ISO values up to 25600.
- Improved Pro features description.
- Made "Restore purchases" option more accessible.

View file

@ -0,0 +1,4 @@
- Added shutter speed values up to 1/4000.
- Added auto scaling for long values in the exposure pairs list.
- Fixed false purchasable status when offline.
- Fixed a delay when fetching product status on startup.

View file

@ -0,0 +1,2 @@
- [Pro] Added the ability to create custom films.
- [Pro] Added the ability to select equipment profiles in use.

View file

@ -0,0 +1 @@
- Performance improvements and bug fixes.

View file

@ -0,0 +1 @@
- Cleaned up camera preview implementation.

Some files were not shown because too many files have changed in this diff Show more