Upgrade project to the latest stable Flutter version (#201)
* 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
3
.fvmrc
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"flutter": "3.27.1"
|
||||||
|
}
|
11
.github/workflows/build_apk.yml
vendored
|
@ -90,7 +90,7 @@ jobs:
|
||||||
- uses: actions/setup-java@v3
|
- uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
distribution: "zulu"
|
distribution: "zulu"
|
||||||
java-version: "11"
|
java-version: "17"
|
||||||
|
|
||||||
- name: Restore Android keystore .jsk and .properties files
|
- name: Restore Android keystore .jsk and .properties files
|
||||||
run: |
|
run: |
|
||||||
|
@ -100,8 +100,10 @@ jobs:
|
||||||
- name: Restore google-services.json
|
- name: Restore google-services.json
|
||||||
run: bash .github/scripts/restore_from_base64.sh "${{ secrets.GOOGLE_SERVICES_JSON_ANDROID }}" "android/app/google-services.json"
|
run: bash .github/scripts/restore_from_base64.sh "${{ secrets.GOOGLE_SERVICES_JSON_ANDROID }}" "android/app/google-services.json"
|
||||||
|
|
||||||
- name: Restore firebase_options.dart
|
- name: Setup Firebase
|
||||||
run: bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_OPTIONS }}" "lib/firebase_options.dart"
|
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
|
- name: Restore constants.dart
|
||||||
env:
|
env:
|
||||||
|
@ -112,6 +114,7 @@ jobs:
|
||||||
run: bash ./.github/scripts/increment_build_number.sh ${{ github.event.inputs.version }}
|
run: bash ./.github/scripts/increment_build_number.sh ${{ github.event.inputs.version }}
|
||||||
|
|
||||||
- name: Download release notes
|
- name: Download release notes
|
||||||
|
continue-on-error: true
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
|
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
|
||||||
|
@ -121,7 +124,7 @@ jobs:
|
||||||
uses: subosito/flutter-action@v2
|
uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
channel: "stable"
|
channel: "stable"
|
||||||
flutter-version: "3.13.9"
|
flutter-version: "3.27.1"
|
||||||
|
|
||||||
- name: Prepare flutter project
|
- name: Prepare flutter project
|
||||||
run: |
|
run: |
|
||||||
|
|
16
.github/workflows/build_ipa.yml
vendored
|
@ -45,7 +45,7 @@ env:
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build .ipa
|
name: Build .ipa
|
||||||
runs-on: macos-13
|
runs-on: macos-latest
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
@ -92,11 +92,11 @@ jobs:
|
||||||
- name: Restore ExportOptions.plist
|
- name: Restore ExportOptions.plist
|
||||||
run: bash .github/scripts/restore_from_base64.sh "${{ secrets.APP_STORE_EXPORT_OPTIONS }}" "ios/Runner/ExportOptions.plist"
|
run: bash .github/scripts/restore_from_base64.sh "${{ secrets.APP_STORE_EXPORT_OPTIONS }}" "ios/Runner/ExportOptions.plist"
|
||||||
|
|
||||||
- name: Restore firebase_app_id_file.json
|
- name: Setup Firebase
|
||||||
run: bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_APP_ID_FILE }}" "ios/firebase_app_id_file.json"
|
run: |
|
||||||
|
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_APP_ID_FILE }}" "ios/firebase_app_id_file.json"
|
||||||
- name: Restore firebase_options.dart
|
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_OPTIONS }}" "lib/firebase_options.dart"
|
||||||
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
|
- name: Restore constants.dart
|
||||||
env:
|
env:
|
||||||
|
@ -107,6 +107,7 @@ jobs:
|
||||||
run: bash ./.github/scripts/increment_build_number.sh ${{ github.event.inputs.version }}
|
run: bash ./.github/scripts/increment_build_number.sh ${{ github.event.inputs.version }}
|
||||||
|
|
||||||
- name: Download release notes
|
- name: Download release notes
|
||||||
|
continue-on-error: true
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
|
name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
|
||||||
|
@ -116,13 +117,14 @@ jobs:
|
||||||
uses: subosito/flutter-action@v2
|
uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
channel: "stable"
|
channel: "stable"
|
||||||
flutter-version: "3.13.9"
|
flutter-version: "3.27.1"
|
||||||
|
|
||||||
- name: Prepare flutter project
|
- name: Prepare flutter project
|
||||||
run: |
|
run: |
|
||||||
flutter --version
|
flutter --version
|
||||||
flutter pub get
|
flutter pub get
|
||||||
flutter pub run intl_utils:generate
|
flutter pub run intl_utils:generate
|
||||||
|
dart pub global activate flutterfire_cli
|
||||||
|
|
||||||
- name: Build .ipa
|
- name: Build .ipa
|
||||||
run: |
|
run: |
|
||||||
|
|
2
.github/workflows/pr_check.yml
vendored
|
@ -42,7 +42,7 @@ jobs:
|
||||||
- uses: subosito/flutter-action@v2
|
- uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
channel: "stable"
|
channel: "stable"
|
||||||
flutter-version: "3.13.9"
|
flutter-version: "3.27.1"
|
||||||
|
|
||||||
- name: Prepare flutter project
|
- name: Prepare flutter project
|
||||||
run: |
|
run: |
|
||||||
|
|
4
.github/workflows/run_integration_tests.yml
vendored
|
@ -27,11 +27,12 @@ jobs:
|
||||||
bash .github/scripts/restore_from_base64.sh "${{ secrets.CONSTANTS }}" "lib/constants.dart"
|
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.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_APP_ID_FILE }}" "ios/firebase_app_id_file.json"
|
||||||
|
bash .github/scripts/restore_from_base64.sh "${{ secrets.FIREBASE_JSON }}" "firebase.json"
|
||||||
|
|
||||||
- uses: subosito/flutter-action@v2
|
- uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
channel: "stable"
|
channel: "stable"
|
||||||
flutter-version: "3.13.9"
|
flutter-version: "3.27.1"
|
||||||
|
|
||||||
- name: Prepare app
|
- name: Prepare app
|
||||||
run: |
|
run: |
|
||||||
|
@ -39,6 +40,7 @@ jobs:
|
||||||
flutter pub get
|
flutter pub get
|
||||||
flutter pub run intl_utils:generate
|
flutter pub run intl_utils:generate
|
||||||
flutter analyze lib --fatal-infos
|
flutter analyze lib --fatal-infos
|
||||||
|
dart pub global activate flutterfire_cli
|
||||||
|
|
||||||
- name: Launch iOS simulator
|
- name: Launch iOS simulator
|
||||||
uses: futureware-tech/simulator-action@v3
|
uses: futureware-tech/simulator-action@v3
|
||||||
|
|
5
.gitignore
vendored
|
@ -5,9 +5,11 @@
|
||||||
*.swp
|
*.swp
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.atom/
|
.atom/
|
||||||
|
.build/
|
||||||
.buildlog/
|
.buildlog/
|
||||||
.history
|
.history
|
||||||
.svn/
|
.svn/
|
||||||
|
.swiftpm/
|
||||||
migrate_working_dir/
|
migrate_working_dir/
|
||||||
|
|
||||||
# IntelliJ related
|
# IntelliJ related
|
||||||
|
@ -48,7 +50,6 @@ app.*.map.json
|
||||||
/ios/build/
|
/ios/build/
|
||||||
/ios/Runner.xcodeproj/project.pbxproj
|
/ios/Runner.xcodeproj/project.pbxproj
|
||||||
|
|
||||||
pubspec.lock
|
|
||||||
/ios/Podfile.lock
|
/ios/Podfile.lock
|
||||||
|
|
||||||
.fvm/
|
.fvm/
|
||||||
|
@ -64,3 +65,5 @@ coverage/
|
||||||
test/coverage_helper_test.dart
|
test/coverage_helper_test.dart
|
||||||
**/failures/*.png
|
**/failures/*.png
|
||||||
screenshots/generated/raw/
|
screenshots/generated/raw/
|
||||||
|
|
||||||
|
firebase.json
|
6
.vscode/settings.json
vendored
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"task.slowProviderWarning": true,
|
"task.slowProviderWarning": true,
|
||||||
"dart.flutterSdkPath": "fvm",
|
"dart.flutterSdkPath": ".fvm/flutter_sdk",
|
||||||
"search.exclude": {
|
"search.exclude": {
|
||||||
"**/.fvm": true
|
"**/.fvm": true
|
||||||
},
|
},
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
"dart.lineLength": 120,
|
"dart.lineLength": 120,
|
||||||
"[dart]": {
|
"[dart]": {
|
||||||
"editor.rulers": [
|
"editor.rulers": [
|
||||||
120,
|
120
|
||||||
],
|
],
|
||||||
"editor.selectionHighlight": true,
|
"editor.selectionHighlight": true,
|
||||||
"editor.suggest.snippetsPreventQuickSuggestions": false,
|
"editor.suggest.snippetsPreventQuickSuggestions": false,
|
||||||
|
@ -21,5 +21,5 @@
|
||||||
"dart.doNotFormat": [
|
"dart.doNotFormat": [
|
||||||
"**/generated/**",
|
"**/generated/**",
|
||||||
"lib/data/**"
|
"lib/data/**"
|
||||||
],
|
]
|
||||||
}
|
}
|
|
@ -34,7 +34,7 @@ Without further delay behold my new Lightmeter app inspired by Material You (a.k
|
||||||
|
|
||||||
### 1. Install Flutter
|
### 1. Install Flutter
|
||||||
|
|
||||||
To build this app you need to install Flutter 3.13.9 stable. [How to install](https://docs.flutter.dev/get-started/install).
|
To build this app you need to install Flutter 3.27.1 stable. [How to install](https://docs.flutter.dev/get-started/install).
|
||||||
|
|
||||||
### 2. Project setup
|
### 2. Project setup
|
||||||
|
|
||||||
|
|
|
@ -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 localProperties = new Properties()
|
||||||
def localPropertiesFile = rootProject.file('local.properties')
|
def localPropertiesFile = rootProject.file('local.properties')
|
||||||
if (localPropertiesFile.exists()) {
|
if (localPropertiesFile.exists()) {
|
||||||
|
@ -6,11 +14,6 @@ if (localPropertiesFile.exists()) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
|
||||||
if (flutterRoot == null) {
|
|
||||||
throw GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
|
||||||
}
|
|
||||||
|
|
||||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||||
if (flutterVersionCode == null) {
|
if (flutterVersionCode == null) {
|
||||||
flutterVersionCode = '1'
|
flutterVersionCode = '1'
|
||||||
|
@ -27,15 +30,9 @@ if (keystorePropertiesFile.exists()) {
|
||||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
|
||||||
apply plugin: 'com.google.firebase.crashlytics'
|
|
||||||
apply plugin: 'kotlin-android'
|
|
||||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 34
|
compileSdkVersion 34
|
||||||
ndkVersion flutter.ndkVersion
|
ndkVersion "27.0.12077973"
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
@ -43,7 +40,7 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = '1.8'
|
jvmTarget = JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
@ -51,7 +48,7 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 21
|
minSdkVersion 23
|
||||||
targetSdkVersion 34
|
targetSdkVersion 34
|
||||||
ndk {
|
ndk {
|
||||||
debugSymbolLevel 'FULL'
|
debugSymbolLevel 'FULL'
|
||||||
|
@ -101,6 +98,7 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
namespace 'com.vodemn.lightmeter'
|
||||||
}
|
}
|
||||||
|
|
||||||
flutter {
|
flutter {
|
||||||
|
@ -108,7 +106,6 @@ flutter {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
|
||||||
implementation "com.android.billingclient:billing-ktx:6.0.0"
|
implementation "com.android.billingclient:billing-ktx:6.0.0"
|
||||||
implementation "com.google.firebase:firebase-analytics:17.4.1"
|
implementation "com.google.firebase:firebase-analytics:17.4.1"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
package="com.vodemn.lightmeter">
|
|
||||||
<!-- The INTERNET permission is required for development. Specifically,
|
<!-- The INTERNET permission is required for development. Specifically,
|
||||||
the Flutter tool needs it to communicate with the running application
|
the Flutter tool needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
package="com.vodemn.lightmeter">
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
package="com.vodemn.lightmeter">
|
|
||||||
<!-- The INTERNET permission is required for development. Specifically,
|
<!-- The INTERNET permission is required for development. Specifically,
|
||||||
the Flutter tool needs it to communicate with the running application
|
the Flutter tool needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
buildscript {
|
|
||||||
ext.kotlin_version = '1.8.21'
|
|
||||||
repositories {
|
|
||||||
google()
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
classpath 'com.android.tools.build:gradle:7.4.2'
|
|
||||||
classpath 'com.google.gms:google-services:4.3.15'
|
|
||||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
|
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
org.gradle.jvmargs=-Xmx1536M
|
org.gradle.jvmargs=-Xmx1536M
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
android.defaults.buildfeatures.buildconfig=true
|
||||||
|
android.nonTransitiveRClass=false
|
||||||
|
android.nonFinalResIds=false
|
||||||
|
|
|
@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip
|
||||||
|
|
|
@ -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")
|
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
||||||
def properties = new Properties()
|
|
||||||
|
|
||||||
assert localPropertiesFile.exists()
|
repositories {
|
||||||
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
gradlePluginPortal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
plugins {
|
||||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||||
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
|
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"
|
|
@ -13,7 +13,7 @@ dependencies:
|
||||||
git:
|
git:
|
||||||
url: "https://github.com/vodemn/m3_lightmeter_resources"
|
url: "https://github.com/vodemn/m3_lightmeter_resources"
|
||||||
ref: v2.1.0
|
ref: v2.1.0
|
||||||
shared_preferences: 2.2.0
|
shared_preferences:
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
@ -21,6 +21,6 @@
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.0</string>
|
<string>1.0</string>
|
||||||
<key>MinimumOSVersion</key>
|
<key>MinimumOSVersion</key>
|
||||||
<string>11.0</string>
|
<string>12.0</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
12
ios/Podfile
|
@ -1,5 +1,5 @@
|
||||||
# Uncomment this line to define a global platform for your project
|
# Uncomment this line to define a global platform for your project
|
||||||
platform :ios, '12.0'
|
platform :ios, '13.0'
|
||||||
|
|
||||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||||
|
@ -36,6 +36,16 @@ end
|
||||||
|
|
||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
installer.pods_project.targets.each do |target|
|
installer.pods_project.targets.each do |target|
|
||||||
|
if target.name == 'BoringSSL-GRPC'
|
||||||
|
target.source_build_phase.files.each do |file|
|
||||||
|
if file.settings && file.settings['COMPILER_FLAGS']
|
||||||
|
flags = file.settings['COMPILER_FLAGS'].split
|
||||||
|
flags.reject! { |flag| flag == '-GCC_WARN_INHIBIT_ALL_WARNINGS' }
|
||||||
|
file.settings['COMPILER_FLAGS'] = flags.join(' ')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
flutter_additional_ios_build_settings(target)
|
flutter_additional_ios_build_settings(target)
|
||||||
|
|
||||||
target.build_configurations.each do |config|
|
target.build_configurations.each do |config|
|
||||||
|
|
|
@ -155,6 +155,8 @@
|
||||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||||
45F53C083F2EA48EF231DA16 /* [CP] Embed Pods Frameworks */,
|
45F53C083F2EA48EF231DA16 /* [CP] Embed Pods Frameworks */,
|
||||||
FF00F85CE432774850A0EDB7 /* [firebase_crashlytics] Crashlytics Upload Symbols */,
|
FF00F85CE432774850A0EDB7 /* [firebase_crashlytics] Crashlytics Upload Symbols */,
|
||||||
|
08127035D2CDEEEBA66FCDBB /* [CP] Copy Pods Resources */,
|
||||||
|
6F6C086A620B15784F8BE312 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
|
@ -171,7 +173,7 @@
|
||||||
97C146E61CF9000F007C117D /* Project object */ = {
|
97C146E61CF9000F007C117D /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastUpgradeCheck = 1300;
|
LastUpgradeCheck = 1510;
|
||||||
ORGANIZATIONNAME = "";
|
ORGANIZATIONNAME = "";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
97C146ED1CF9000F007C117D = {
|
97C146ED1CF9000F007C117D = {
|
||||||
|
@ -214,6 +216,23 @@
|
||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
08127035D2CDEEEBA66FCDBB /* [CP] Copy Pods Resources */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
|
);
|
||||||
|
name = "[CP] Copy Pods Resources";
|
||||||
|
outputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
385E047940E442D45ED68E6E /* [CP] Check Pods Manifest.lock */ = {
|
385E047940E442D45ED68E6E /* [CP] Check Pods Manifest.lock */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -269,6 +288,24 @@
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
|
6F6C086A620B15784F8BE312 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
name = "FlutterFire: \"flutterfire upload-crashlytics-symbols\"";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\n#!/bin/bash\nPATH=\"${PATH}:$FLUTTER_ROOT/bin:$HOME/.pub-cache/bin\"\nflutterfire upload-crashlytics-symbols --upload-symbols-script-path=\"$PODS_ROOT/FirebaseCrashlytics/upload-symbols\" --platform=ios --apple-project-path=\"${SRCROOT}\" --env-platform-name=\"${PLATFORM_NAME}\" --env-configuration=\"${CONFIGURATION}\" --env-project-dir=\"${PROJECT_DIR}\" --env-built-products-dir=\"${BUILT_PRODUCTS_DIR}\" --env-dwarf-dsym-folder-path=\"${DWARF_DSYM_FOLDER_PATH}\" --env-dwarf-dsym-file-name=\"${DWARF_DSYM_FILE_NAME}\" --env-infoplist-path=\"${INFOPLIST_PATH}\" --default-config=default\n";
|
||||||
|
};
|
||||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
alwaysOutOfDate = 1;
|
alwaysOutOfDate = 1;
|
||||||
|
@ -292,11 +329,11 @@
|
||||||
inputFileListPaths = (
|
inputFileListPaths = (
|
||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
"\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}\"",
|
"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}",
|
||||||
"\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/\"",
|
"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${PRODUCT_NAME}",
|
||||||
"\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist\"",
|
"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist",
|
||||||
"\"$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)\"",
|
"$(BUILT_PRODUCTS_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/GoogleService-Info.plist",
|
||||||
"\"$(PROJECT_DIR)/firebase_app_id_file.json\"",
|
"$(BUILT_PRODUCTS_DIR)/$(EXECUTABLE_PATH)",
|
||||||
);
|
);
|
||||||
name = "[firebase_crashlytics] Crashlytics Upload Symbols";
|
name = "[firebase_crashlytics] Crashlytics Upload Symbols";
|
||||||
outputFileListPaths = (
|
outputFileListPaths = (
|
||||||
|
@ -305,7 +342,7 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "\"$PODS_ROOT/FirebaseCrashlytics/upload-symbols\" --flutter-project \"$PROJECT_DIR/firebase_app_id_file.json\" ";
|
shellScript = "\"${PODS_ROOT}/FirebaseCrashlytics/upload-symbols\" -gsp \"${PROJECT_DIR}/Runner/GoogleService-Info.plist\" -p ios \"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}\"\n";
|
||||||
};
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
|
@ -382,7 +419,7 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
|
@ -397,6 +434,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-prod";
|
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-prod";
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||||
|
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
@ -466,7 +504,7 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
@ -515,7 +553,7 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
|
@ -532,6 +570,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-prod";
|
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-prod";
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||||
|
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
@ -561,6 +600,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-prod";
|
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-prod";
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||||
|
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||||
|
@ -633,7 +673,7 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
@ -647,6 +687,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-dev";
|
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-dev";
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||||
|
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
@ -711,7 +752,7 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
|
@ -728,6 +769,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-dev";
|
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-dev";
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||||
|
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
@ -791,7 +833,7 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
|
@ -806,6 +848,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-dev";
|
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-dev";
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||||
|
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import UIKit
|
import UIKit
|
||||||
import Flutter
|
import Flutter
|
||||||
|
|
||||||
@UIApplicationMain
|
@main
|
||||||
@objc class AppDelegate: FlutterAppDelegate {
|
@objc class AppDelegate: FlutterAppDelegate {
|
||||||
override func application(
|
override func application(
|
||||||
_ application: UIApplication,
|
_ application: UIApplication,
|
||||||
|
|
|
@ -44,7 +44,7 @@ class Application extends StatelessWidget {
|
||||||
],
|
],
|
||||||
supportedLocales: S.delegate.supportedLocales,
|
supportedLocales: S.delegate.supportedLocales,
|
||||||
builder: (context, child) => MediaQuery(
|
builder: (context, child) => MediaQuery(
|
||||||
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
|
data: MediaQuery.of(context).copyWith(textScaler: TextScaler.noScaling),
|
||||||
child: child!,
|
child: child!,
|
||||||
),
|
),
|
||||||
initialRoute: NavigationRoutes.meteringScreen.name,
|
initialRoute: NavigationRoutes.meteringScreen.name,
|
||||||
|
|
|
@ -22,7 +22,7 @@ class LightmeterAnalytics {
|
||||||
|
|
||||||
Future<void> logEvent(
|
Future<void> logEvent(
|
||||||
String eventName, {
|
String eventName, {
|
||||||
Map<String, dynamic>? parameters,
|
Map<String, Object>? parameters,
|
||||||
}) async {
|
}) async {
|
||||||
if (!kReleaseMode) {
|
if (!kReleaseMode) {
|
||||||
log('<LightmeterAnalytics> logEvent: $eventName / $parameters');
|
log('<LightmeterAnalytics> logEvent: $eventName / $parameters');
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
abstract class ILightmeterAnalyticsApi {
|
abstract class ILightmeterAnalyticsApi {
|
||||||
Future<void> logEvent(
|
Future<void> logEvent(
|
||||||
String eventName, {
|
String eventName, {
|
||||||
Map<String, dynamic>? parameters,
|
Map<String, Object>? parameters,
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<void> logCrash(
|
Future<void> logCrash(
|
||||||
|
|
|
@ -10,7 +10,7 @@ class LightmeterAnalyticsFirebase implements ILightmeterAnalyticsApi {
|
||||||
@override
|
@override
|
||||||
Future<void> logEvent(
|
Future<void> logEvent(
|
||||||
String eventName, {
|
String eventName, {
|
||||||
Map<String, dynamic>? parameters,
|
Map<String, Object>? parameters,
|
||||||
}) async {
|
}) async {
|
||||||
try {
|
try {
|
||||||
await FirebaseAnalytics.instance.logEvent(
|
await FirebaseAnalytics.instance.logEvent(
|
||||||
|
|
|
@ -8,7 +8,7 @@ typedef MeteringScreenLayoutConfig = Map<MeteringScreenLayoutFeature, bool>;
|
||||||
|
|
||||||
extension MeteringScreenLayoutConfigJson on MeteringScreenLayoutConfig {
|
extension MeteringScreenLayoutConfigJson on MeteringScreenLayoutConfig {
|
||||||
static MeteringScreenLayoutConfig fromJson(Map<String, dynamic> data) {
|
static MeteringScreenLayoutConfig fromJson(Map<String, dynamic> data) {
|
||||||
int? migratedIndex(MeteringScreenLayoutFeature feature) {
|
int migratedIndex(MeteringScreenLayoutFeature feature) {
|
||||||
switch (feature) {
|
switch (feature) {
|
||||||
case MeteringScreenLayoutFeature.extremeExposurePairs:
|
case MeteringScreenLayoutFeature.extremeExposurePairs:
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -16,8 +16,6 @@ extension MeteringScreenLayoutConfigJson on MeteringScreenLayoutConfig {
|
||||||
return 1;
|
return 1;
|
||||||
case MeteringScreenLayoutFeature.equipmentProfiles:
|
case MeteringScreenLayoutFeature.equipmentProfiles:
|
||||||
return 3;
|
return 3;
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
|
||||||
import 'package:lightmeter/data/models/supported_locale.dart';
|
import 'package:lightmeter/data/models/supported_locale.dart';
|
||||||
import 'package:lightmeter/data/models/theme_type.dart';
|
import 'package:lightmeter/data/models/theme_type.dart';
|
||||||
import 'package:lightmeter/data/models/volume_action.dart';
|
import 'package:lightmeter/data/models/volume_action.dart';
|
||||||
|
import 'package:lightmeter/utils/color_to_int.dart';
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
@ -155,7 +156,7 @@ class UserPreferencesService {
|
||||||
set themeType(ThemeType value) => _sharedPreferences.setInt(themeTypeKey, value.index);
|
set themeType(ThemeType value) => _sharedPreferences.setInt(themeTypeKey, value.index);
|
||||||
|
|
||||||
Color get primaryColor => Color(_sharedPreferences.getInt(primaryColorKey) ?? 0xff2196f3);
|
Color get primaryColor => Color(_sharedPreferences.getInt(primaryColorKey) ?? 0xff2196f3);
|
||||||
set primaryColor(Color value) => _sharedPreferences.setInt(primaryColorKey, value.value);
|
set primaryColor(Color value) => _sharedPreferences.setInt(primaryColorKey, value.toInt());
|
||||||
|
|
||||||
bool get dynamicColor => _sharedPreferences.getBool(dynamicColorKey) ?? false;
|
bool get dynamicColor => _sharedPreferences.getBool(dynamicColorKey) ?? false;
|
||||||
set dynamicColor(bool value) => _sharedPreferences.setBool(dynamicColorKey, value);
|
set dynamicColor(bool value) => _sharedPreferences.setBool(dynamicColorKey, value);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
import 'package:lightmeter/res/dimens.dart';
|
||||||
|
import 'package:lightmeter/utils/color_to_int.dart';
|
||||||
import 'package:material_color_utilities/material_color_utilities.dart';
|
import 'package:material_color_utilities/material_color_utilities.dart';
|
||||||
|
|
||||||
const primaryColorsList = [
|
const primaryColorsList = [
|
||||||
|
@ -32,7 +33,7 @@ ThemeData themeFrom(Color primaryColor, Brightness brightness) {
|
||||||
elevation: Dimens.elevationLevel0,
|
elevation: Dimens.elevationLevel0,
|
||||||
scrolledUnderElevation: Dimens.elevationLevel2,
|
scrolledUnderElevation: Dimens.elevationLevel2,
|
||||||
color: scheme.surface,
|
color: scheme.surface,
|
||||||
foregroundColor: scheme.onBackground,
|
foregroundColor: scheme.onSurface,
|
||||||
surfaceTintColor: scheme.surfaceTint,
|
surfaceTintColor: scheme.surfaceTint,
|
||||||
),
|
),
|
||||||
cardTheme: CardTheme(
|
cardTheme: CardTheme(
|
||||||
|
@ -75,15 +76,13 @@ ThemeData themeFrom(Color primaryColor, Brightness brightness) {
|
||||||
|
|
||||||
ColorScheme _colorSchemeFromColor(Color primaryColor, Brightness brightness) {
|
ColorScheme _colorSchemeFromColor(Color primaryColor, Brightness brightness) {
|
||||||
final scheme = SchemeTonalSpot(
|
final scheme = SchemeTonalSpot(
|
||||||
sourceColorHct: Hct.fromInt(primaryColor.value),
|
sourceColorHct: Hct.fromInt(primaryColor.toInt()),
|
||||||
isDark: brightness == Brightness.dark,
|
isDark: brightness == Brightness.dark,
|
||||||
contrastLevel: 0.0,
|
contrastLevel: 0.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
return ColorScheme(
|
return ColorScheme(
|
||||||
brightness: brightness,
|
brightness: brightness,
|
||||||
background: Color(scheme.background),
|
|
||||||
onBackground: Color(scheme.onBackground),
|
|
||||||
error: Color(scheme.error),
|
error: Color(scheme.error),
|
||||||
onError: Color(scheme.onError),
|
onError: Color(scheme.onError),
|
||||||
errorContainer: Color(scheme.errorContainer),
|
errorContainer: Color(scheme.errorContainer),
|
||||||
|
@ -102,7 +101,7 @@ ColorScheme _colorSchemeFromColor(Color primaryColor, Brightness brightness) {
|
||||||
onTertiaryContainer: Color(scheme.onTertiaryContainer),
|
onTertiaryContainer: Color(scheme.onTertiaryContainer),
|
||||||
surface: Color(scheme.surface),
|
surface: Color(scheme.surface),
|
||||||
onSurface: Color(scheme.onSurface),
|
onSurface: Color(scheme.onSurface),
|
||||||
surfaceVariant: Color(scheme.surfaceVariant),
|
surfaceContainerHighest: Color(scheme.surfaceContainerHighest),
|
||||||
onSurfaceVariant: Color(scheme.onSurfaceVariant),
|
onSurfaceVariant: Color(scheme.onSurfaceVariant),
|
||||||
outline: Color(scheme.outline),
|
outline: Color(scheme.outline),
|
||||||
outlineVariant: Color(scheme.outlineVariant),
|
outlineVariant: Color(scheme.outlineVariant),
|
||||||
|
|
|
@ -91,7 +91,6 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
|
||||||
case communication_states.SettingsClosedState():
|
case communication_states.SettingsClosedState():
|
||||||
_settingsOpened = false;
|
_settingsOpened = false;
|
||||||
add(const InitializeEvent());
|
add(const InitializeEvent());
|
||||||
default:
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ class CameraControlsPlaceholder extends StatelessWidget {
|
||||||
const SizedBox(height: Dimens.grid8),
|
const SizedBox(height: Dimens.grid8),
|
||||||
Text(
|
Text(
|
||||||
error.toStringLocalized(context),
|
error.toStringLocalized(context),
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Theme.of(context).colorScheme.onBackground),
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Theme.of(context).colorScheme.onSurface),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -62,14 +62,14 @@ class _Title<T extends PhotographyStopValue> extends StatelessWidget {
|
||||||
value.toString(),
|
value.toString(),
|
||||||
stepGranularity: 0.5,
|
stepGranularity: 0.5,
|
||||||
minFontSize: 10,
|
minFontSize: 10,
|
||||||
style: labelTextStyle(context).copyWith(color: Theme.of(context).colorScheme.onBackground),
|
style: labelTextStyle(context).copyWith(color: Theme.of(context).colorScheme.onSurface),
|
||||||
softWrap: false,
|
softWrap: false,
|
||||||
overflow: TextOverflow.fade,
|
overflow: TextOverflow.fade,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
)
|
)
|
||||||
: Text(
|
: Text(
|
||||||
value.toString(),
|
value.toString(),
|
||||||
style: labelTextStyle(context).copyWith(color: Theme.of(context).colorScheme.onBackground),
|
style: labelTextStyle(context).copyWith(color: Theme.of(context).colorScheme.onSurface),
|
||||||
softWrap: false,
|
softWrap: false,
|
||||||
overflow: TextOverflow.fade,
|
overflow: TextOverflow.fade,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
|
@ -97,7 +97,7 @@ class _Tick extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ColoredBox(
|
return ColoredBox(
|
||||||
color: Theme.of(context).colorScheme.onBackground,
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 1,
|
height: 1,
|
||||||
width: _length,
|
width: _length,
|
||||||
|
|
|
@ -78,7 +78,7 @@ class ExposurePairsList extends StatelessWidget {
|
||||||
? constraints.maxHeight / 2
|
? constraints.maxHeight / 2
|
||||||
: constraints.maxHeight,
|
: constraints.maxHeight,
|
||||||
child: ColoredBox(
|
child: ColoredBox(
|
||||||
color: Theme.of(context).colorScheme.onBackground,
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
child: const SizedBox(width: 1),
|
child: const SizedBox(width: 1),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -178,8 +178,8 @@ class AnimatedDialogState extends State<AnimatedDialog> with SingleTickerProvide
|
||||||
opaque: false,
|
opaque: false,
|
||||||
transitionDuration: Duration.zero,
|
transitionDuration: Duration.zero,
|
||||||
reverseTransitionDuration: Duration.zero,
|
reverseTransitionDuration: Duration.zero,
|
||||||
pageBuilder: (_, __, ___) => WillPopScope(
|
pageBuilder: (_, __, ___) => PopScope(
|
||||||
onWillPop: () => _animateReverse().then((value) => true),
|
onPopInvokedWithResult: (_, __) => _animateReverse().then((value) => true),
|
||||||
child: _AnimatedOverlay(
|
child: _AnimatedOverlay(
|
||||||
controller: _animationController,
|
controller: _animationController,
|
||||||
barrierColorAnimation: _barrierColorAnimation,
|
barrierColorAnimation: _barrierColorAnimation,
|
||||||
|
@ -221,7 +221,13 @@ class AnimatedDialogState extends State<AnimatedDialog> with SingleTickerProvide
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> close() => _animateReverse().then((_) => Navigator.of(context).pop());
|
Future<void> close() {
|
||||||
|
return _animateReverse().then((_) {
|
||||||
|
if (mounted) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AnimatedOverlay extends StatelessWidget {
|
class _AnimatedOverlay extends StatelessWidget {
|
||||||
|
|
|
@ -69,9 +69,14 @@ class MeteringScreen extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
void pushNamed(BuildContext context, String routeName, {Object? arguments}) {
|
void pushNamed(BuildContext context, String routeName, {Object? arguments}) {
|
||||||
context.read<MeteringBloc>().add(const ScreenOnTopOpenedEvent());
|
final bloc = context.read<MeteringBloc>();
|
||||||
Navigator.pushNamed(context, routeName, arguments: arguments).then((_) {
|
bloc.add(const ScreenOnTopOpenedEvent());
|
||||||
context.read<MeteringBloc>().add(const ScreenOnTopClosedEvent());
|
Navigator.pushNamed(
|
||||||
|
context,
|
||||||
|
routeName,
|
||||||
|
arguments: arguments,
|
||||||
|
).then((_) {
|
||||||
|
bloc.add(const ScreenOnTopClosedEvent());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,14 @@ import 'package:lightmeter/constants.dart';
|
||||||
import 'package:lightmeter/generated/l10n.dart';
|
import 'package:lightmeter/generated/l10n.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
class WriteEmailListTile extends StatelessWidget {
|
class WriteEmailListTile extends StatefulWidget {
|
||||||
const WriteEmailListTile({super.key});
|
const WriteEmailListTile({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<WriteEmailListTile> createState() => _WriteEmailListTileState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _WriteEmailListTileState extends State<WriteEmailListTile> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
|
@ -20,7 +25,15 @@ class WriteEmailListTile extends StatelessWidget {
|
||||||
mailToUrl,
|
mailToUrl,
|
||||||
mode: LaunchMode.externalApplication,
|
mode: LaunchMode.externalApplication,
|
||||||
);
|
);
|
||||||
} else {
|
} else if (mounted) {
|
||||||
|
_showSnackBar();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _showSnackBar() async {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(S.of(context).youDontHaveMailApp),
|
content: Text(S.of(context).youDontHaveMailApp),
|
||||||
|
@ -29,15 +42,13 @@ class WriteEmailListTile extends StatelessWidget {
|
||||||
label: S.of(context).copyEmail,
|
label: S.of(context).copyEmail,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
FlutterClipboard.copy(contactEmail).then((_) {
|
FlutterClipboard.copy(contactEmail).then((_) {
|
||||||
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).clearSnackBars();
|
ScaffoldMessenger.of(context).clearSnackBars();
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ class LanguageListTile extends StatelessWidget {
|
||||||
title: Text(S.of(context).language),
|
title: Text(S.of(context).language),
|
||||||
trailing: Text(UserPreferencesProvider.localeOf(context).localizedName),
|
trailing: Text(UserPreferencesProvider.localeOf(context).localizedName),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
final prefs = UserPreferencesProvider.of(context);
|
||||||
showDialog<SupportedLocale>(
|
showDialog<SupportedLocale>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (_) => DialogPicker<SupportedLocale>(
|
builder: (_) => DialogPicker<SupportedLocale>(
|
||||||
|
@ -21,11 +22,11 @@ class LanguageListTile extends StatelessWidget {
|
||||||
title: S.of(context).chooseLanguage,
|
title: S.of(context).chooseLanguage,
|
||||||
selectedValue: UserPreferencesProvider.localeOf(context),
|
selectedValue: UserPreferencesProvider.localeOf(context),
|
||||||
values: SupportedLocale.values,
|
values: SupportedLocale.values,
|
||||||
titleAdapter: (context, value) => value.localizedName,
|
titleAdapter: (_, value) => value.localizedName,
|
||||||
),
|
),
|
||||||
).then((value) {
|
).then((value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
UserPreferencesProvider.of(context).setLocale(value);
|
prefs.setLocale(value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,6 +14,7 @@ class StopTypeListTile extends StatelessWidget {
|
||||||
title: Text(S.of(context).fractionalStops),
|
title: Text(S.of(context).fractionalStops),
|
||||||
trailing: Text(_typeToString(context, UserPreferencesProvider.stopTypeOf(context))),
|
trailing: Text(_typeToString(context, UserPreferencesProvider.stopTypeOf(context))),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
final prefs = UserPreferencesProvider.of(context);
|
||||||
showDialog<StopType>(
|
showDialog<StopType>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (_) => DialogPicker<StopType>(
|
builder: (_) => DialogPicker<StopType>(
|
||||||
|
@ -25,7 +26,7 @@ class StopTypeListTile extends StatelessWidget {
|
||||||
),
|
),
|
||||||
).then((value) {
|
).then((value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
UserPreferencesProvider.of(context).setStopType(value);
|
prefs.setStopType(value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:lightmeter/generated/l10n.dart';
|
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
|
||||||
|
|
||||||
class ExpandableSectionNameDialog extends StatefulWidget {
|
|
||||||
final String title;
|
|
||||||
final String hint;
|
|
||||||
final String initialValue;
|
|
||||||
|
|
||||||
const ExpandableSectionNameDialog({
|
|
||||||
this.initialValue = '',
|
|
||||||
required this.title,
|
|
||||||
required this.hint,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<ExpandableSectionNameDialog> createState() => _ExpandableSectionNameDialogState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ExpandableSectionNameDialogState extends State<ExpandableSectionNameDialog> {
|
|
||||||
late final _nameController = TextEditingController(text: widget.initialValue);
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_nameController.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return AlertDialog(
|
|
||||||
icon: const Icon(Icons.edit_outlined),
|
|
||||||
titlePadding: Dimens.dialogIconTitlePadding,
|
|
||||||
title: Text(widget.title),
|
|
||||||
content: TextField(
|
|
||||||
autofocus: true,
|
|
||||||
controller: _nameController,
|
|
||||||
decoration: InputDecoration(hintText: widget.hint),
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: Navigator.of(context).pop,
|
|
||||||
child: Text(S.of(context).cancel),
|
|
||||||
),
|
|
||||||
ValueListenableBuilder(
|
|
||||||
valueListenable: _nameController,
|
|
||||||
builder: (_, value, __) => TextButton(
|
|
||||||
onPressed: value.text.isNotEmpty ? () => Navigator.of(context).pop(value.text) : null,
|
|
||||||
child: Text(S.of(context).save),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,184 +0,0 @@
|
||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter/scheduler.dart';
|
|
||||||
import 'package:lightmeter/generated/l10n.dart';
|
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
|
||||||
|
|
||||||
class ExpandableSectionListItem extends StatefulWidget {
|
|
||||||
final String title;
|
|
||||||
final VoidCallback onTitleTap;
|
|
||||||
final VoidCallback onExpand;
|
|
||||||
final List<IconButton> actions;
|
|
||||||
final List<Widget> children;
|
|
||||||
|
|
||||||
const ExpandableSectionListItem({
|
|
||||||
required this.title,
|
|
||||||
required this.onTitleTap,
|
|
||||||
required this.onExpand,
|
|
||||||
required this.actions,
|
|
||||||
required this.children,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
static ExpandableSectionListItemState of(BuildContext context) {
|
|
||||||
return context.findAncestorStateOfType<ExpandableSectionListItemState>()!;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<ExpandableSectionListItem> createState() => ExpandableSectionListItemState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class ExpandableSectionListItemState extends State<ExpandableSectionListItem> with TickerProviderStateMixin {
|
|
||||||
late final AnimationController _controller = AnimationController(
|
|
||||||
duration: Dimens.durationM,
|
|
||||||
vsync: this,
|
|
||||||
);
|
|
||||||
bool get _expanded => _controller.isCompleted;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_controller.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Card(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: Dimens.paddingM),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
ListTile(
|
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: Dimens.paddingM),
|
|
||||||
title: Row(
|
|
||||||
children: [
|
|
||||||
_AnimatedNameLeading(controller: _controller),
|
|
||||||
const SizedBox(width: Dimens.grid8),
|
|
||||||
Flexible(
|
|
||||||
child: Text(
|
|
||||||
widget.title,
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
trailing: _AnimatedArrowButton(
|
|
||||||
controller: _controller,
|
|
||||||
onPressed: () => _expanded ? collapse() : expand(),
|
|
||||||
),
|
|
||||||
onTap: () => _expanded ? widget.onTitleTap() : expand(),
|
|
||||||
),
|
|
||||||
_AnimatedContent(
|
|
||||||
controller: _controller,
|
|
||||||
actions: widget.actions,
|
|
||||||
children: widget.children,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void expand() {
|
|
||||||
widget.onExpand();
|
|
||||||
_controller.forward();
|
|
||||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
|
||||||
Future.delayed(_controller.duration!).then((_) {
|
|
||||||
Scrollable.ensureVisible(
|
|
||||||
context,
|
|
||||||
alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtEnd,
|
|
||||||
duration: _controller.duration!,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void collapse() {
|
|
||||||
_controller.reverse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _AnimatedNameLeading extends AnimatedWidget {
|
|
||||||
const _AnimatedNameLeading({required AnimationController controller}) : super(listenable: controller);
|
|
||||||
|
|
||||||
Animation<double> get _progress => listenable as Animation<double>;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.only(right: _progress.value * Dimens.grid8),
|
|
||||||
child: Icon(
|
|
||||||
Icons.edit_outlined,
|
|
||||||
size: _progress.value * Dimens.grid24,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _AnimatedArrowButton extends AnimatedWidget {
|
|
||||||
final VoidCallback onPressed;
|
|
||||||
|
|
||||||
const _AnimatedArrowButton({
|
|
||||||
required AnimationController controller,
|
|
||||||
required this.onPressed,
|
|
||||||
}) : super(listenable: controller);
|
|
||||||
|
|
||||||
Animation<double> get _progress => listenable as Animation<double>;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return IconButton(
|
|
||||||
onPressed: onPressed,
|
|
||||||
icon: Transform.rotate(
|
|
||||||
angle: _progress.value * pi,
|
|
||||||
child: const Icon(Icons.keyboard_arrow_down_outlined),
|
|
||||||
),
|
|
||||||
tooltip: _progress.value == 0 ? S.of(context).tooltipExpand : S.of(context).tooltipCollapse,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _AnimatedContent extends AnimatedWidget {
|
|
||||||
final List<IconButton> actions;
|
|
||||||
final List<Widget> children;
|
|
||||||
|
|
||||||
const _AnimatedContent({
|
|
||||||
required AnimationController controller,
|
|
||||||
required this.actions,
|
|
||||||
required this.children,
|
|
||||||
}) : super(listenable: controller);
|
|
||||||
|
|
||||||
Animation<double> get _progress => listenable as Animation<double>;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return SizedOverflowBox(
|
|
||||||
alignment: Alignment.topCenter,
|
|
||||||
size: Size(
|
|
||||||
double.maxFinite,
|
|
||||||
_progress.value * Dimens.grid56 * (children.length + 1),
|
|
||||||
),
|
|
||||||
// https://github.com/gskinnerTeam/flutter-folio/pull/62
|
|
||||||
child: Opacity(
|
|
||||||
opacity: _progress.value,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
...children,
|
|
||||||
ListTile(
|
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: Dimens.paddingM),
|
|
||||||
trailing: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: actions,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
|
||||||
import 'package:lightmeter/screens/settings/components/shared/expandable_section_list/components/expandable_section_list_item/widget_expandable_section_list_item.dart';
|
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
|
||||||
|
|
||||||
typedef _WidgetBuilder<W, T extends Identifiable> = W Function(BuildContext context, T value);
|
|
||||||
|
|
||||||
class ExpandableSectionList<T extends Identifiable> extends StatefulWidget {
|
|
||||||
final List<T> values;
|
|
||||||
final VoidCallback onSectionTitleTap;
|
|
||||||
final _WidgetBuilder<List<Widget>, T> contentBuilder;
|
|
||||||
final _WidgetBuilder<List<IconButton>, T> actionsBuilder;
|
|
||||||
|
|
||||||
const ExpandableSectionList({
|
|
||||||
required this.values,
|
|
||||||
required this.onSectionTitleTap,
|
|
||||||
required this.contentBuilder,
|
|
||||||
required this.actionsBuilder,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<ExpandableSectionList> createState() => _ExpandableSectionListState<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ExpandableSectionListState<T extends Identifiable> extends State<ExpandableSectionList<T>> {
|
|
||||||
final Map<String, GlobalKey<ExpandableSectionListItemState>> keysMap = {};
|
|
||||||
|
|
||||||
@override
|
|
||||||
void didChangeDependencies() {
|
|
||||||
super.didChangeDependencies();
|
|
||||||
_updateProfilesKeys();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return SliverList(
|
|
||||||
delegate: SliverChildBuilderDelegate(
|
|
||||||
(context, index) {
|
|
||||||
final item = widget.values[index];
|
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.fromLTRB(
|
|
||||||
Dimens.paddingM,
|
|
||||||
index == 0 ? Dimens.paddingM : 0,
|
|
||||||
Dimens.paddingM,
|
|
||||||
Dimens.paddingM,
|
|
||||||
),
|
|
||||||
child: ExpandableSectionListItem(
|
|
||||||
key: keysMap[item.id],
|
|
||||||
title: item.name,
|
|
||||||
onTitleTap: widget.onSectionTitleTap,
|
|
||||||
onExpand: () => _keepExpandedAt(index),
|
|
||||||
actions: widget.actionsBuilder(context, item),
|
|
||||||
children: widget.contentBuilder(context, item),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
childCount: widget.values.length,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _keepExpandedAt(int index) {
|
|
||||||
keysMap.values.toList().getRange(0, index).forEach((element) {
|
|
||||||
element.currentState?.collapse();
|
|
||||||
});
|
|
||||||
keysMap.values.toList().getRange(index + 1, keysMap.length).forEach((element) {
|
|
||||||
element.currentState?.collapse();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _updateProfilesKeys() {
|
|
||||||
if (widget.values.length > keysMap.length) {
|
|
||||||
// item added
|
|
||||||
final List<String> idsToAdd = [];
|
|
||||||
for (final item in widget.values) {
|
|
||||||
if (!keysMap.keys.contains(item.id)) idsToAdd.add(item.id);
|
|
||||||
}
|
|
||||||
for (final id in idsToAdd) {
|
|
||||||
keysMap[id] = GlobalKey<ExpandableSectionListItemState>(debugLabel: id);
|
|
||||||
}
|
|
||||||
idsToAdd.clear();
|
|
||||||
} else if (widget.values.length < keysMap.length) {
|
|
||||||
// item deleted
|
|
||||||
final List<String> idsToDelete = [];
|
|
||||||
for (final id in keysMap.keys) {
|
|
||||||
if (!widget.values.any((p) => p.id == id)) idsToDelete.add(id);
|
|
||||||
}
|
|
||||||
idsToDelete.forEach(keysMap.remove);
|
|
||||||
idsToDelete.clear();
|
|
||||||
} else {
|
|
||||||
// item updated, no need to updated keys
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,6 +3,7 @@ import 'package:lightmeter/generated/l10n.dart';
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
import 'package:lightmeter/res/dimens.dart';
|
||||||
import 'package:lightmeter/res/theme.dart';
|
import 'package:lightmeter/res/theme.dart';
|
||||||
import 'package:lightmeter/screens/shared/filled_circle/widget_circle_filled.dart';
|
import 'package:lightmeter/screens/shared/filled_circle/widget_circle_filled.dart';
|
||||||
|
import 'package:lightmeter/utils/color_to_int.dart';
|
||||||
|
|
||||||
class PrimaryColorDialogPicker extends StatefulWidget {
|
class PrimaryColorDialogPicker extends StatefulWidget {
|
||||||
const PrimaryColorDialogPicker({super.key});
|
const PrimaryColorDialogPicker({super.key});
|
||||||
|
@ -45,7 +46,7 @@ class _PrimaryColorDialogPickerState extends State<PrimaryColorDialogPicker> {
|
||||||
padding: EdgeInsets.only(left: index == 0 ? 0 : Dimens.paddingS),
|
padding: EdgeInsets.only(left: index == 0 ? 0 : Dimens.paddingS),
|
||||||
child: _SelectableColorItem(
|
child: _SelectableColorItem(
|
||||||
color: color,
|
color: color,
|
||||||
selected: color.value == _selected.value,
|
selected: color.toInt() == _selected.toInt(),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_selected = color;
|
_selected = color;
|
||||||
|
|
|
@ -22,12 +22,13 @@ class PrimaryColorListTile extends StatelessWidget {
|
||||||
leading: const Icon(Icons.palette_outlined),
|
leading: const Icon(Icons.palette_outlined),
|
||||||
title: Text(S.of(context).primaryColor),
|
title: Text(S.of(context).primaryColor),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
final prefs = UserPreferencesProvider.of(context);
|
||||||
showDialog<Color>(
|
showDialog<Color>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (_) => const PrimaryColorDialogPicker(),
|
builder: (_) => const PrimaryColorDialogPicker(),
|
||||||
).then((value) {
|
).then((value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
UserPreferencesProvider.of(context).setPrimaryColor(value);
|
prefs.setPrimaryColor(value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,6 +14,7 @@ class ThemeTypeListTile extends StatelessWidget {
|
||||||
title: Text(S.of(context).theme),
|
title: Text(S.of(context).theme),
|
||||||
trailing: Text(_typeToString(context, UserPreferencesProvider.themeTypeOf(context))),
|
trailing: Text(_typeToString(context, UserPreferencesProvider.themeTypeOf(context))),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
final prefs = UserPreferencesProvider.of(context);
|
||||||
showDialog<ThemeType>(
|
showDialog<ThemeType>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (_) => DialogPicker<ThemeType>(
|
builder: (_) => DialogPicker<ThemeType>(
|
||||||
|
@ -25,7 +26,7 @@ class ThemeTypeListTile extends StatelessWidget {
|
||||||
),
|
),
|
||||||
).then((value) {
|
).then((value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
UserPreferencesProvider.of(context).setThemeType(value);
|
prefs.setThemeType(value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -120,7 +120,7 @@ class _Slider extends StatelessWidget {
|
||||||
width: handleDistance + trackThickness,
|
width: handleDistance + trackThickness,
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(trackThickness / 2),
|
borderRadius: BorderRadius.circular(trackThickness / 2),
|
||||||
child: ColoredBox(color: Theme.of(context).colorScheme.surfaceVariant),
|
child: ColoredBox(color: Theme.of(context).colorScheme.surfaceContainerHighest),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
AnimatedPositioned.fromRect(
|
AnimatedPositioned.fromRect(
|
||||||
|
|
|
@ -20,15 +20,12 @@ class IconPlaceholder extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
Icon(
|
||||||
icon,
|
icon,
|
||||||
color: Theme.of(context).colorScheme.onBackground,
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
),
|
),
|
||||||
const SizedBox(height: Dimens.grid8),
|
const SizedBox(height: Dimens.grid8),
|
||||||
Text(
|
Text(
|
||||||
text,
|
text,
|
||||||
style: Theme.of(context)
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Theme.of(context).colorScheme.onSurface),
|
||||||
.textTheme
|
|
||||||
.bodyMedium
|
|
||||||
?.copyWith(color: Theme.of(context).colorScheme.onBackground),
|
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -21,10 +21,11 @@ class ReleaseNotesFlow extends StatelessWidget {
|
||||||
child: BlocListener<ReleaseNotesBloc, ReleaseNotesState>(
|
child: BlocListener<ReleaseNotesBloc, ReleaseNotesState>(
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
if (state is ShowReleaseNotesDialogState) {
|
if (state is ShowReleaseNotesDialogState) {
|
||||||
|
final bloc = context.read<ReleaseNotesBloc>();
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (_) => ReleaseNotesDialog(version: state.version),
|
builder: (_) => ReleaseNotesDialog(version: state.version),
|
||||||
).then((_) => context.read<ReleaseNotesBloc>().setChangelogVersion());
|
).then((_) => bloc.setChangelogVersion());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: child,
|
child: child,
|
||||||
|
|
|
@ -30,7 +30,7 @@ class RulerSlider extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
valueAdapter(value),
|
valueAdapter(value),
|
||||||
style: Theme.of(context).textTheme.labelLarge!.copyWith(color: Theme.of(context).colorScheme.onBackground),
|
style: Theme.of(context).textTheme.labelLarge!.copyWith(color: Theme.of(context).colorScheme.onSurface),
|
||||||
),
|
),
|
||||||
const SizedBox(height: Dimens.grid4),
|
const SizedBox(height: Dimens.grid4),
|
||||||
Expanded(
|
Expanded(
|
||||||
|
@ -78,7 +78,7 @@ class _Ruler extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final mainTicksFontSize = Theme.of(context).textTheme.bodySmall!.fontSize!;
|
final mainTicksFontSize = Theme.of(context).textTheme.bodySmall!.fontSize!;
|
||||||
final itemsColor = Theme.of(context).colorScheme.onBackground;
|
final itemsColor = Theme.of(context).colorScheme.onSurface;
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(
|
||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
final bool showAllMainTicks =
|
final bool showAllMainTicks =
|
||||||
|
|
12
lib/utils/color_to_int.dart
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
extension ColorToInt on Color {
|
||||||
|
int toInt() {
|
||||||
|
final a = (this.a * 255).round();
|
||||||
|
final r = (this.r * 255).round();
|
||||||
|
final g = (this.g * 255).round();
|
||||||
|
final b = (this.b * 255).round();
|
||||||
|
|
||||||
|
return (a << 24) | (r << 16) | (g << 8) | b;
|
||||||
|
}
|
||||||
|
}
|
1565
pubspec.lock
Normal file
66
pubspec.yaml
|
@ -7,61 +7,61 @@ environment:
|
||||||
sdk: ">=3.0.0 <4.0.0"
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
app_settings: 4.2.0
|
app_settings: 5.1.1
|
||||||
auto_size_text: 3.0.0
|
auto_size_text: 3.0.0
|
||||||
bloc_concurrency: 0.2.2
|
bloc_concurrency: 0.3.0
|
||||||
camera: 0.10.5+2
|
camera: 0.11.0+2
|
||||||
camera_android_camerax: 0.6.1+1
|
|
||||||
clipboard: 0.1.3
|
clipboard: 0.1.3
|
||||||
collection: any
|
collection: any
|
||||||
dynamic_color: 1.7.0
|
dynamic_color: 1.7.0
|
||||||
exif: 3.1.4
|
exif: 3.3.0
|
||||||
firebase_analytics: 10.6.2
|
firebase_analytics: 11.4.0
|
||||||
firebase_core: 2.20.0
|
firebase_core: 3.10.0
|
||||||
firebase_crashlytics: 3.4.2
|
firebase_crashlytics: 4.3.0
|
||||||
firebase_remote_config: 4.3.2
|
firebase_remote_config: 5.3.0
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_bloc: 8.1.3
|
flutter_bloc: 9.0.0
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_native_splash: 2.3.5
|
flutter_native_splash: 2.4.4
|
||||||
intl: 0.18.1
|
intl: 0.19.0
|
||||||
intl_utils: 2.8.2
|
intl_utils: 2.8.7
|
||||||
light_sensor: 3.0.0
|
light_sensor: 3.0.1
|
||||||
m3_lightmeter_iap:
|
m3_lightmeter_iap:
|
||||||
git:
|
git:
|
||||||
url: "https://github.com/vodemn/m3_lightmeter_iap"
|
url: "https://github.com/vodemn/m3_lightmeter_iap"
|
||||||
ref: v2.1.0
|
ref: v2.1.1
|
||||||
m3_lightmeter_resources:
|
m3_lightmeter_resources:
|
||||||
git:
|
git:
|
||||||
url: "https://github.com/vodemn/m3_lightmeter_resources"
|
url: "https://github.com/vodemn/m3_lightmeter_resources"
|
||||||
ref: v2.1.0
|
ref: v2.1.0
|
||||||
material_color_utilities: 0.5.0
|
material_color_utilities: 0.12.0
|
||||||
package_info_plus: 4.2.0
|
package_info_plus: 8.1.3
|
||||||
permission_handler: 10.4.3
|
permission_handler: 11.3.1
|
||||||
platform: 3.1.0
|
platform: 3.1.5
|
||||||
shared_preferences: 2.2.0
|
shared_preferences: 2.3.5
|
||||||
url_launcher: 6.1.12
|
url_launcher:
|
||||||
uuid: 3.0.7
|
url_launcher_ios: 6.3.2
|
||||||
vibration: 1.8.1
|
uuid: 4.5.1
|
||||||
|
vibration: 2.0.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
args: 2.5.0
|
args: 2.6.0
|
||||||
bloc_test: 9.1.3
|
bloc_test: 10.0.0
|
||||||
build_runner: 2.4.6
|
build_runner: 2.4.14
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
golden_toolkit: 0.15.0
|
golden_toolkit: 0.15.0
|
||||||
google_fonts: 3.0.1
|
google_fonts: 6.2.1
|
||||||
image: 4.1.7
|
image: 4.3.0
|
||||||
integration_test:
|
integration_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
lint: 2.1.2
|
lint: 2.3.0
|
||||||
logging: 1.2.0
|
logging: 1.3.0
|
||||||
meta: 1.9.1
|
meta: 1.15.0
|
||||||
mocktail: 0.3.0
|
mocktail: 1.0.4
|
||||||
test: 1.24.3
|
test: 1.25.8
|
||||||
|
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
material_color_utilities: 0.11.1
|
material_color_utilities: 0.11.1
|
||||||
|
|
|
@ -22,6 +22,7 @@ import 'package:lightmeter/screens/metering/screen_metering.dart';
|
||||||
import 'package:lightmeter/screens/settings/screen_settings.dart';
|
import 'package:lightmeter/screens/settings/screen_settings.dart';
|
||||||
import 'package:lightmeter/screens/shared/animated_circular_button/widget_button_circular_animated.dart';
|
import 'package:lightmeter/screens/shared/animated_circular_button/widget_button_circular_animated.dart';
|
||||||
import 'package:lightmeter/screens/timer/screen_timer.dart';
|
import 'package:lightmeter/screens/timer/screen_timer.dart';
|
||||||
|
import 'package:lightmeter/utils/color_to_int.dart';
|
||||||
import 'package:lightmeter/utils/platform_utils.dart';
|
import 'package:lightmeter/utils/platform_utils.dart';
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
@ -77,7 +78,7 @@ void main() {
|
||||||
|
|
||||||
/// Theme settings
|
/// Theme settings
|
||||||
UserPreferencesService.themeTypeKey: theme.index,
|
UserPreferencesService.themeTypeKey: theme.index,
|
||||||
UserPreferencesService.primaryColorKey: color.value,
|
UserPreferencesService.primaryColorKey: color.toInt(),
|
||||||
UserPreferencesService.dynamicColorKey: false,
|
UserPreferencesService.dynamicColorKey: false,
|
||||||
|
|
||||||
UserPreferencesService.seenChangelogVersionKey: await const PlatformUtils().version,
|
UserPreferencesService.seenChangelogVersionKey: await const PlatformUtils().version,
|
||||||
|
@ -190,7 +191,7 @@ extension on WidgetTester {
|
||||||
name: name,
|
name: name,
|
||||||
deviceName: const String.fromEnvironment('deviceName'),
|
deviceName: const String.fromEnvironment('deviceName'),
|
||||||
platformFolder: _platformFolder,
|
platformFolder: _platformFolder,
|
||||||
backgroundColor: backgroundColor.value.toRadixString(16),
|
backgroundColor: backgroundColor.toInt().toRadixString(16),
|
||||||
isDark: theme.brightness == Brightness.dark,
|
isDark: theme.brightness == Brightness.dark,
|
||||||
).toString(),
|
).toString(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -47,7 +47,7 @@ class WidgetTestApplicationMock extends StatelessWidget {
|
||||||
],
|
],
|
||||||
supportedLocales: S.delegate.supportedLocales,
|
supportedLocales: S.delegate.supportedLocales,
|
||||||
builder: (context, child) => MediaQuery(
|
builder: (context, child) => MediaQuery(
|
||||||
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
|
data: MediaQuery.of(context).copyWith(textScaler: TextScaler.noScaling),
|
||||||
child: child!,
|
child: child!,
|
||||||
),
|
),
|
||||||
home: Scaffold(body: child),
|
home: Scaffold(body: child),
|
||||||
|
@ -124,7 +124,7 @@ class _GoldenTestApplicationMockState extends State<GoldenTestApplicationMock> {
|
||||||
],
|
],
|
||||||
supportedLocales: S.delegate.supportedLocales,
|
supportedLocales: S.delegate.supportedLocales,
|
||||||
builder: (context, child) => MediaQuery(
|
builder: (context, child) => MediaQuery(
|
||||||
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
|
data: MediaQuery.of(context).copyWith(textScaler: TextScaler.noScaling),
|
||||||
child: child!,
|
child: child!,
|
||||||
),
|
),
|
||||||
home: widget.child,
|
home: widget.child,
|
||||||
|
|
Before Width: | Height: | Size: 301 KiB After Width: | Height: | Size: 301 KiB |
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 1.5 MiB |
Before Width: | Height: | Size: 494 KiB After Width: | Height: | Size: 498 KiB |
Before Width: | Height: | Size: 858 KiB After Width: | Height: | Size: 863 KiB |