diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies new file mode 100644 index 0000000..21700ac --- /dev/null +++ b/.flutter-plugins-dependencies @@ -0,0 +1 @@ +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_secure_storage","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.4/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"flutter_secure_storage","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_android","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/path_provider_android-2.2.17/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_android","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/shared_preferences_android-2.4.10/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"flutter_secure_storage_macos","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/flutter_secure_storage_macos-3.1.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.4/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"flutter_secure_storage_linux","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/flutter_secure_storage_linux-1.2.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_linux","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_linux","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/","native_build":false,"dependencies":["path_provider_linux"],"dev_dependency":false}],"windows":[{"name":"flutter_secure_storage_windows","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/flutter_secure_storage_windows-3.1.2/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_windows","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_windows","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/","native_build":false,"dependencies":["path_provider_windows"],"dev_dependency":false}],"web":[{"name":"flutter_secure_storage_web","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/flutter_secure_storage_web-1.2.1/","dependencies":[],"dev_dependency":false},{"name":"shared_preferences_web","path":"/Users/basemosama/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.3/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"flutter_secure_storage","dependencies":["flutter_secure_storage_linux","flutter_secure_storage_macos","flutter_secure_storage_web","flutter_secure_storage_windows"]},{"name":"flutter_secure_storage_linux","dependencies":[]},{"name":"flutter_secure_storage_macos","dependencies":[]},{"name":"flutter_secure_storage_web","dependencies":[]},{"name":"flutter_secure_storage_windows","dependencies":["path_provider"]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]}],"date_created":"2025-06-29 20:46:13.013234","version":"3.32.4","swift_package_manager_enabled":{"ios":false,"macos":false}} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index af015a7..85df812 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 1.1.0 +> **Note**: This release contains breaking changes. +- Updated to Flutter 3.27 / Dart 3.5. +- Updated dependencies. +- Added `context.themeData` and `context.isDarkMode` extensions. +- Added `logThemeChanges` option to `PlayxThemeConfig` to log theme changes. +- Theme update methods now support `animate` parameter to enable animation or not: + * `updateTo`, `updateByIndex`, `updateById`, `next`, + `updateToDeviceMode`, `updateToLightMode`, `updateToDarkMode`, `updateByThemeMode`. + + ## 1.0.4 - Update packages - Updates minimum supported SDK version to Flutter 3.24/Dart 3.5. diff --git a/example/.gitignore b/example/.gitignore index 1eab1a2..13f4101 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -5,9 +5,11 @@ *.swp .DS_Store .atom/ +.build/ .buildlog/ .history .svn/ +.swiftpm/ migrate_working_dir/ # IntelliJ related diff --git a/example/.metadata b/example/.metadata index b02a7e4..603c641 100644 --- a/example/.metadata +++ b/example/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled and should not be manually edited. version: - revision: "17025dd88227cd9532c33fa78f5250d548d87e9a" + revision: "6fba2447e95c451518584c35e25f5433f14d888c" channel: "stable" project_type: app @@ -13,26 +13,26 @@ project_type: app migration: platforms: - platform: root - create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a - base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + create_revision: 6fba2447e95c451518584c35e25f5433f14d888c + base_revision: 6fba2447e95c451518584c35e25f5433f14d888c - platform: android - create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a - base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + create_revision: 6fba2447e95c451518584c35e25f5433f14d888c + base_revision: 6fba2447e95c451518584c35e25f5433f14d888c - platform: ios - create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a - base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + create_revision: 6fba2447e95c451518584c35e25f5433f14d888c + base_revision: 6fba2447e95c451518584c35e25f5433f14d888c - platform: linux - create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a - base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + create_revision: 6fba2447e95c451518584c35e25f5433f14d888c + base_revision: 6fba2447e95c451518584c35e25f5433f14d888c - platform: macos - create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a - base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + create_revision: 6fba2447e95c451518584c35e25f5433f14d888c + base_revision: 6fba2447e95c451518584c35e25f5433f14d888c - platform: web - create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a - base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + create_revision: 6fba2447e95c451518584c35e25f5433f14d888c + base_revision: 6fba2447e95c451518584c35e25f5433f14d888c - platform: windows - create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a - base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + create_revision: 6fba2447e95c451518584c35e25f5433f14d888c + base_revision: 6fba2447e95c451518584c35e25f5433f14d888c # User provided section diff --git a/example/android/.gitignore b/example/android/.gitignore index 55afd91..be3943c 100644 --- a/example/android/.gitignore +++ b/example/android/.gitignore @@ -5,6 +5,7 @@ gradle-wrapper.jar /gradlew.bat /local.properties GeneratedPluginRegistrant.java +.cxx/ # Remember to never publicly share your keystore. # See https://flutter.dev/to/reference-keystore diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle deleted file mode 100644 index a235834..0000000 --- a/example/android/app/build.gradle +++ /dev/null @@ -1,39 +0,0 @@ -plugins { - id "com.android.application" - id "kotlin-android" - // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. - id "dev.flutter.flutter-gradle-plugin" -} - -android { - namespace = "com.example.example" - compileSdk = flutter.compileSdkVersion - ndkVersion = flutter.ndkVersion - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - - kotlinOptions { - jvmTarget = JavaVersion.VERSION_1_8 - } - - defaultConfig { - applicationId = "io.souryca.play.theme.example" - minSdk = flutter.minSdkVersion - targetSdk = flutter.targetSdkVersion - versionCode = flutter.versionCode - versionName = flutter.versionName - } - - buildTypes { - release { - signingConfig = signingConfigs.debug - } - } -} - -flutter { - source = "../.." -} diff --git a/example/android/app/build.gradle.kts b/example/android/app/build.gradle.kts new file mode 100644 index 0000000..a6ae87b --- /dev/null +++ b/example/android/app/build.gradle.kts @@ -0,0 +1,44 @@ +plugins { + id("com.android.application") + id("kotlin-android") + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id("dev.flutter.flutter-gradle-plugin") +} + +android { + namespace = "com.example.example" + compileSdk = flutter.compileSdkVersion + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_17.toString() + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId = "io.sourcya.playx.theme.example" + // You can update the following values to match your application needs. + // For more information, see: https://flutter.dev/to/review-gradle-config. + minSdk = 23 + targetSdk = flutter.targetSdkVersion + versionCode = flutter.versionCode + versionName = flutter.versionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig = signingConfigs.getByName("debug") + } + } +} + +flutter { + source = "../.." +} diff --git a/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt b/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt index 70f8f08..ac81bae 100644 --- a/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt +++ b/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt @@ -2,4 +2,4 @@ package com.example.example import io.flutter.embedding.android.FlutterActivity -class MainActivity: FlutterActivity() +class MainActivity : FlutterActivity() diff --git a/example/android/build.gradle b/example/android/build.gradle deleted file mode 100644 index d2ffbff..0000000 --- a/example/android/build.gradle +++ /dev/null @@ -1,18 +0,0 @@ -allprojects { - repositories { - google() - mavenCentral() - } -} - -rootProject.buildDir = "../build" -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(":app") -} - -tasks.register("clean", Delete) { - delete rootProject.buildDir -} diff --git a/example/android/build.gradle.kts b/example/android/build.gradle.kts new file mode 100644 index 0000000..89176ef --- /dev/null +++ b/example/android/build.gradle.kts @@ -0,0 +1,21 @@ +allprojects { + repositories { + google() + mavenCentral() + } +} + +val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get() +rootProject.layout.buildDirectory.value(newBuildDir) + +subprojects { + val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) + project.layout.buildDirectory.value(newSubprojectBuildDir) +} +subprojects { + project.evaluationDependsOn(":app") +} + +tasks.register("clean") { + delete(rootProject.layout.buildDirectory) +} diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 2597170..f018a61 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -1,3 +1,3 @@ -org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true android.enableJetifier=true diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index 7bb2df6..348c409 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -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-8.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip diff --git a/example/android/settings.gradle b/example/android/settings.gradle deleted file mode 100644 index a42444d..0000000 --- a/example/android/settings.gradle +++ /dev/null @@ -1,25 +0,0 @@ -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 - }() - - includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") - - repositories { - google() - mavenCentral() - gradlePluginPortal() - } -} - -plugins { - id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "8.2.1" apply false - id "org.jetbrains.kotlin.android" version "1.8.22" apply false -} - -include ":app" diff --git a/example/android/settings.gradle.kts b/example/android/settings.gradle.kts new file mode 100644 index 0000000..ab39a10 --- /dev/null +++ b/example/android/settings.gradle.kts @@ -0,0 +1,25 @@ +pluginManagement { + val flutterSdkPath = run { + val properties = java.util.Properties() + file("local.properties").inputStream().use { properties.load(it) } + val flutterSdkPath = properties.getProperty("flutter.sdk") + require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } + flutterSdkPath + } + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +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 "2.1.0" apply false +} + +include(":app") diff --git a/example/ios/Flutter/Debug.xcconfig b/example/ios/Flutter/Debug.xcconfig index 592ceee..ec97fc6 100644 --- a/example/ios/Flutter/Debug.xcconfig +++ b/example/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/example/ios/Flutter/Release.xcconfig b/example/ios/Flutter/Release.xcconfig index 592ceee..c4855bf 100644 --- a/example/ios/Flutter/Release.xcconfig +++ b/example/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/example/ios/Podfile b/example/ios/Podfile new file mode 100644 index 0000000..e549ee2 --- /dev/null +++ b/example/ios/Podfile @@ -0,0 +1,43 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '12.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock new file mode 100644 index 0000000..802f4b0 --- /dev/null +++ b/example/ios/Podfile.lock @@ -0,0 +1,36 @@ +PODS: + - Flutter (1.0.0) + - flutter_secure_storage (6.0.0): + - Flutter + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + +DEPENDENCIES: + - Flutter (from `Flutter`) + - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) + - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) + - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + flutter_secure_storage: + :path: ".symlinks/plugins/flutter_secure_storage/ios" + path_provider_foundation: + :path: ".symlinks/plugins/path_provider_foundation/darwin" + shared_preferences_foundation: + :path: ".symlinks/plugins/shared_preferences_foundation/darwin" + +SPEC CHECKSUMS: + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13 + path_provider_foundation: 2a68637f8a62df7f6e790a428d1bdf72cb4e2d59 + shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 + +PODFILE CHECKSUM: 4305caec6b40dde0ae97be1573c53de1882a07e5 + +COCOAPODS: 1.16.2 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index ce3bc8f..5311fda 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -7,9 +7,11 @@ objects = { /* Begin PBXBuildFile section */ + 027C41C53F7EA11B363F7CEE /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58100D785B8381965E761A84 /* Pods_RunnerTests.framework */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 501DFFFE5F44BE814B64CA33 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D70C59916B2CE758DDA65251 /* Pods_Runner.framework */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; @@ -42,12 +44,18 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 2B55CEC16374C97B1F7FD3F7 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; + 32DB9AE68E55BBF5A29AF668 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 58100D785B8381965E761A84 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 72844A78B3B7BA7A46B3015C /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 8BBAD55512C68F9C62A905CD /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + 90614ACA6469111DB43A6537 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -55,6 +63,8 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + C10D29E8D98FBAA73047DE0D /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + D70C59916B2CE758DDA65251 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -62,6 +72,15 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 501DFFFE5F44BE814B64CA33 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E44BAFAE9231659EABAADB5D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 027C41C53F7EA11B363F7CEE /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -76,6 +95,29 @@ path = RunnerTests; sourceTree = ""; }; + 659CBB81DE03BCEFA8BD1C15 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D70C59916B2CE758DDA65251 /* Pods_Runner.framework */, + 58100D785B8381965E761A84 /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 8467BEF447BE00ACDE38DC85 /* Pods */ = { + isa = PBXGroup; + children = ( + 90614ACA6469111DB43A6537 /* Pods-Runner.debug.xcconfig */, + 32DB9AE68E55BBF5A29AF668 /* Pods-Runner.release.xcconfig */, + C10D29E8D98FBAA73047DE0D /* Pods-Runner.profile.xcconfig */, + 2B55CEC16374C97B1F7FD3F7 /* Pods-RunnerTests.debug.xcconfig */, + 8BBAD55512C68F9C62A905CD /* Pods-RunnerTests.release.xcconfig */, + 72844A78B3B7BA7A46B3015C /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -94,6 +136,8 @@ 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, + 8467BEF447BE00ACDE38DC85 /* Pods */, + 659CBB81DE03BCEFA8BD1C15 /* Frameworks */, ); sourceTree = ""; }; @@ -128,8 +172,10 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + D15AACA65C813021D96588F0 /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, 331C807F294A63A400263BE5 /* Resources */, + E44BAFAE9231659EABAADB5D /* Frameworks */, ); buildRules = ( ); @@ -145,12 +191,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + 847E1C0278D499AEC970C504 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 7C2675BC737B66EF8F921C47 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -238,6 +286,45 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 7C2675BC737B66EF8F921C47 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 847E1C0278D499AEC970C504 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -253,6 +340,28 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + D15AACA65C813021D96588F0 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -362,6 +471,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = B996ZRP255; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -378,6 +488,7 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 2B55CEC16374C97B1F7FD3F7 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -395,6 +506,7 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 8BBAD55512C68F9C62A905CD /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -410,6 +522,7 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 72844A78B3B7BA7A46B3015C /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -541,6 +654,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = B996ZRP255; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -563,6 +677,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = B996ZRP255; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 8e3ca5d..e3773d4 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -26,6 +26,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit" shouldUseLaunchSchemeArgsEnv = "YES"> diff --git a/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcworkspace/contents.xcworkspacedata index 1d526a1..21a3cc1 100644 --- a/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/example/lib/main.dart b/example/lib/main.dart index 00685f6..bc7035a 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -106,6 +106,7 @@ class HomeScreen extends StatelessWidget { PlayxTheme .supportedThemes[index] .id, + animate: false, animation: const PlayxThemeAnimation .horizontalSlide()); @@ -140,6 +141,7 @@ class HomeScreen extends StatelessWidget { animation: const PlayxThemeFadeAnimation( duration: Duration(milliseconds: 500), ), + animate: false, ); }, child: const Text('Next Theme'), @@ -153,6 +155,7 @@ class HomeScreen extends StatelessWidget { PlayxTheme.next( animation: PlayxThemeAnimation.clipper( clipper: const ThemeSwitcherCircleClipper(), context: ctx), + animate: false, ); }, tooltip: 'Next Theme', diff --git a/example/macos/Flutter/Flutter-Debug.xcconfig b/example/macos/Flutter/Flutter-Debug.xcconfig index c2efd0b..4b81f9b 100644 --- a/example/macos/Flutter/Flutter-Debug.xcconfig +++ b/example/macos/Flutter/Flutter-Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/example/macos/Flutter/Flutter-Release.xcconfig b/example/macos/Flutter/Flutter-Release.xcconfig index c2efd0b..5caa9d1 100644 --- a/example/macos/Flutter/Flutter-Release.xcconfig +++ b/example/macos/Flutter/Flutter-Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/example/macos/Podfile b/example/macos/Podfile new file mode 100644 index 0000000..29c8eb3 --- /dev/null +++ b/example/macos/Podfile @@ -0,0 +1,42 @@ +platform :osx, '10.14' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 15368ec..ac78810 100644 --- a/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -59,6 +59,7 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" + enableGPUValidationMode = "1" allowLocationSimulation = "YES"> diff --git a/example/pubspec.lock b/example/pubspec.lock index 1ddaec8..d0285cd 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -9,46 +9,54 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.10" + ansicolor: + dependency: transitive + description: + name: ansicolor + sha256: "50e982d500bc863e1d703448afdbf9e5a72eb48840a4f766fa361ffd6877055f" + url: "https://pub.dev" + source: hosted + version: "2.0.3" async: dependency: transitive description: name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" url: "https://pub.dev" source: hosted - version: "2.11.0" + version: "2.13.0" boolean_selector: dependency: transitive description: name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" characters: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" clock: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.1" equatable: dependency: transitive description: @@ -61,34 +69,34 @@ packages: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.3" ffi: dependency: transitive description: name: ffi - sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" + sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" file: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.1" flex_seed_scheme: dependency: transitive description: name: flex_seed_scheme - sha256: "7639d2c86268eff84a909026eb169f008064af0fb3696a651b24b0fa24a40334" + sha256: b06d8b367b84cbf7ca5c5603c858fa5edae88486c4e4da79ac1044d73b6c62ec url: "https://pub.dev" source: hosted - version: "3.4.1" + version: "3.5.1" flutter: dependency: "direct main" description: flutter @@ -106,10 +114,10 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" + sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "6.0.0" flutter_secure_storage: dependency: transitive description: @@ -122,10 +130,10 @@ packages: dependency: transitive description: name: flutter_secure_storage_linux - sha256: bf7404619d7ab5c0a1151d7c4e802edad8f33535abfbeff2f9e1fe1274e2d705 + sha256: be76c1d24a97d0b98f8b54bce6b481a380a6590df992d0098f868ad54dc8f688 url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.2.3" flutter_secure_storage_macos: dependency: transitive description: @@ -188,18 +196,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.9" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.9" leak_tracker_testing: dependency: transitive description: @@ -212,18 +220,18 @@ packages: dependency: transitive description: name: lints - sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413" + sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0 url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "6.0.0" matcher: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.17" material_color_utilities: dependency: transitive description: @@ -236,89 +244,89 @@ packages: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.16.0" path: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" path_provider: dependency: transitive description: name: path_provider - sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2" + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" url: "https://pub.dev" source: hosted - version: "2.0.15" + version: "2.1.5" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86" + sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9 url: "https://pub.dev" source: hosted - version: "2.0.27" + version: "2.2.17" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "916731ccbdce44d545414dd9961f26ba5fbaa74bcbb55237d8e65a623a8c7297" + sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" url: "https://pub.dev" source: hosted - version: "2.2.4" + version: "2.4.1" path_provider_linux: dependency: transitive description: name: path_provider_linux - sha256: "2ae08f2216225427e64ad224a24354221c2c7907e448e6e0e8b57b1eb9f10ad1" + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 url: "https://pub.dev" source: hosted - version: "2.1.10" + version: "2.2.1" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface - sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" url: "https://pub.dev" source: hosted - version: "2.0.6" + version: "2.1.2" path_provider_windows: dependency: transitive description: name: path_provider_windows - sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96" + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 url: "https://pub.dev" source: hosted - version: "2.1.7" + version: "2.3.0" platform: dependency: transitive description: name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.6" playx_core: dependency: transitive description: name: playx_core - sha256: b96bd6fc2dbf3bfeacfec1972b69355118f1e0a3823977a6517eac5389d4fac6 + sha256: "2ec52210e11918d2d4d86580ee9f859da434346ffb2fecbb3f903d931414f369" url: "https://pub.dev" source: hosted - version: "0.6.3" + version: "0.7.3" playx_theme: dependency: "direct main" description: path: ".." relative: true source: path - version: "1.0.4" + version: "1.1.0" plugin_platform_interface: dependency: transitive description: @@ -327,38 +335,30 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" - process: - dependency: transitive - description: - name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" - url: "https://pub.dev" - source: hosted - version: "4.2.4" shared_preferences: dependency: transitive description: name: shared_preferences - sha256: "846849e3e9b68f3ef4b60c60cf4b3e02e9321bc7f4d8c4692cf87ffa82fc8a3a" + sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" url: "https://pub.dev" source: hosted - version: "2.5.2" + version: "2.5.3" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "02a7d8a9ef346c9af715811b01fbd8e27845ad2c41148eefd31321471b41863d" + sha256: "20cbd561f743a342c76c151d6ddb93a9ce6005751e7aa458baad3858bfbfb6ac" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.10" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: c4b35f6cb8f63c147312c054ce7c2254c8066745125264f0c88739c417fc9d9f + sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" url: "https://pub.dev" source: hosted - version: "2.5.2" + version: "2.5.4" shared_preferences_linux: dependency: transitive description: @@ -379,10 +379,10 @@ packages: dependency: transitive description: name: shared_preferences_web - sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e + sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.3" shared_preferences_windows: dependency: transitive description: @@ -395,15 +395,15 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.10.1" sprintf: dependency: transitive description: @@ -416,42 +416,50 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" string_scanner: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.4.1" + talker_logger: + dependency: transitive + description: + name: talker_logger + sha256: f1755d517e5ca8b119b65ad2fc1079746a8d03bd565e75d6b9d5aedf5c1d5b15 + url: "https://pub.dev" + source: hosted + version: "4.9.1" term_glyph: dependency: transitive description: name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" test_api: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.4" vector_math: dependency: transitive description: @@ -464,42 +472,42 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "15.0.0" web: dependency: transitive description: name: web - sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.1.1" win32: - dependency: "direct overridden" + dependency: transitive description: name: win32 - sha256: "154360849a56b7b67331c21f09a386562d88903f90a1099c5987afc1912e1f29" + sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03" url: "https://pub.dev" source: hosted - version: "5.10.0" + version: "5.14.0" worker_manager: dependency: transitive description: name: worker_manager - sha256: "0c6c4e7d246bcbe7221273ef955732dafb097347d536ebe6acd6547d0398c49c" + sha256: af3db5e6c6c8a74ab8f72e25e9d305f8ff60984ca55551397e3c8828ebf30509 url: "https://pub.dev" source: hosted - version: "7.2.2" + version: "7.2.6" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1 + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.1.0" sdks: - dart: ">=3.5.0 <4.0.0" - flutter: ">=3.24.0" + dart: ">=3.8.0 <4.0.0" + flutter: ">=3.27.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 0af9d80..15314d7 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -12,13 +12,11 @@ dependencies: playx_theme: path: ../ -dependency_overrides: - win32: ^5.10.0 dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^5.0.0 + flutter_lints: ^6.0.0 flutter: uses-material-design: true diff --git a/lib/src/config/config.dart b/lib/src/config/config.dart index cd30095..4cb5304 100644 --- a/lib/src/config/config.dart +++ b/lib/src/config/config.dart @@ -18,6 +18,9 @@ class PlayxThemeConfig { /// Whether to migrate preferences to asynchronous preferences. final bool migratePrefsToAsyncPrefs; + /// Whether to log theme changes or not. + final bool logThemeChanges ; + /// Creates a [PlayxThemeConfig] instance. /// /// The [initialThemeIndex] must be non-negative and less than the length of [themes]. @@ -27,6 +30,7 @@ class PlayxThemeConfig { this.saveTheme = true, this.themes = const [], this.migratePrefsToAsyncPrefs = false, + this.logThemeChanges = true, }) : assert(initialThemeIndex >= 0 && initialThemeIndex < themes.length), assert(themes.isNotEmpty); } diff --git a/lib/src/controller/controller.dart b/lib/src/controller/controller.dart index 843cac3..ef656e7 100644 --- a/lib/src/controller/controller.dart +++ b/lib/src/controller/controller.dart @@ -66,6 +66,7 @@ class XThemeController extends ValueNotifier { /// List of available themes. List get availableThemes => config.themes; + static PlayxBaseLogger get logger => PlayxLogger.getLogger('PLAYX THEME')!; /// Initializes the theme controller by loading the last saved theme index if applicable. Future boot() async { @@ -81,6 +82,9 @@ class XThemeController extends ValueNotifier { ) ?? config.themes.first; _instance = this; + logger.info( + 'Initialized with theme: ${value.id} at index: $currentIndex', + ); } /// Retrieves the last saved theme index from preferences. @@ -106,21 +110,35 @@ class XThemeController extends ValueNotifier { /// Updates the theme to one from the available theme list. /// /// The provided [theme] should be in the available themes list in [PlayxThemeConfig]. - /// If [animation] is null, the theme change will not be animated. + /// If [animate] is false, the theme change will not be animated. /// If [animation] is provided, the theme change will be animated based on the animation type. /// If [forceUpdateNonAnimatedTheme] is true, the app's widget tree will be rebuilt. Future _updateTheme({ required XTheme theme, required int index, - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), + bool animate = true, bool forceUpdateNonAnimatedTheme = false, }) async { if (value == theme) { + if (config.logThemeChanges) { + logger + .warning('Theme is already set to ${theme.id}, no update needed.'); + } return; } + if (index < 0 || index >= availableThemes.length) { + throw RangeError( + 'The provided index is out of range of available themes list'); + } + if (config.logThemeChanges) { + logger.info( + 'Updating theme from ${value.id} to ${theme.id} at index $index with animation enabled : ${animation != null}', + ); + } currentIndex = index; - final animate = animation != null && controller != null; - if (animate) { + final shouldAnimate = animate && controller != null; + if (shouldAnimate) { await animateTheme( theme: theme, controller: controller!, animation: animation); } else { @@ -149,21 +167,26 @@ class XThemeController extends ValueNotifier { /// Updates the theme to a specific theme from the available theme list. /// /// The provided [theme] should be in the available themes list in [PlayxThemeConfig]. - /// If [animation] is null, the theme change will not be animated. + /// If [animate] is false, the theme change will not be animated. /// If [animation] is provided, the theme change will be animated based on the animation type. /// If [forceUpdateNonAnimatedTheme] is true, the app's widget tree will be rebuilt. Future updateTo( XTheme theme, { - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), + bool animate = true, bool forceUpdateNonAnimatedTheme = false, }) async { if (!availableThemes.contains(theme)) { + if (config.logThemeChanges) { + logger.error('Theme ${theme.id} not found in available themes.'); + } throw Exception('The provided theme is not in the available theme list'); } return _updateTheme( theme: theme, index: availableThemes.indexOf(theme), animation: animation, + animate: animate, forceUpdateNonAnimatedTheme: forceUpdateNonAnimatedTheme, ); } @@ -172,13 +195,15 @@ class XThemeController extends ValueNotifier { /// /// If there is no next theme, it will switch to the first one. Future nextTheme({ - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), + bool animate = true, bool forceUpdateNonAnimatedTheme = false, }) async { final isLastTheme = currentIndex == config.themes.length - 1; return updateByIndex(isLastTheme ? 0 : currentIndex + 1, animation: animation, + animate: animate, forceUpdateNonAnimatedTheme: forceUpdateNonAnimatedTheme); } @@ -188,10 +213,12 @@ class XThemeController extends ValueNotifier { /// Throws a [RangeError] if the index is out of range. Future updateByIndex( int index, { - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), + bool animate = true, bool forceUpdateNonAnimatedTheme = false, }) async { if (index < 0 || index >= availableThemes.length) { + logger.e('Index $index is out of range for available themes list.'); throw RangeError( 'The provided index is out of range of available themes list'); } @@ -199,6 +226,7 @@ class XThemeController extends ValueNotifier { theme: availableThemes[index], index: index, animation: animation, + animate: animate, forceUpdateNonAnimatedTheme: forceUpdateNonAnimatedTheme); } @@ -208,10 +236,14 @@ class XThemeController extends ValueNotifier { /// Throws an exception if the ID is not found. Future updateById( String id, { - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), + bool animate = true, bool forceUpdateNonAnimatedTheme = false, }) async { if (!availableThemes.any((element) => element.id == id)) { + if (config.logThemeChanges) { + logger.error('Theme with id $id not found in available themes.'); + } throw Exception('The provided id is not in the available themes list'); } @@ -220,6 +252,7 @@ class XThemeController extends ValueNotifier { theme: availableThemes[index], index: index, animation: animation, + animate: animate, forceUpdateNonAnimatedTheme: forceUpdateNonAnimatedTheme); } @@ -234,33 +267,41 @@ class XThemeController extends ValueNotifier { /// /// Throws an exception if no light theme is found. Future updateToLightMode({ + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), bool animate = true, - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), bool forceUpdateNonAnimatedTheme = false, }) { final theme = config.themes.firstWhereOrNull((element) => !element.isDark); if (theme == null) { + if (config.logThemeChanges) { + logger.error('Could not find any light theme in the available themes'); + } throw Exception('Could not find any light theme in the available themes'); } return updateTo(theme, animation: animation, + animate: animate, forceUpdateNonAnimatedTheme: forceUpdateNonAnimatedTheme); } ///Update the theme to the first dark theme in supported themes. ///If there is no dark theme, it will throw an exception. Future updateToDarkMode({ + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), bool animate = true, - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), bool forceUpdateNonAnimatedTheme = false, }) { final theme = config.themes.firstWhereOrNull((element) => element.isDark); if (theme == null) { + if (config.logThemeChanges) { + logger.error('Could not find any dark theme in the available themes'); + } throw Exception('Could not find any dark theme in the available themes'); } return updateTo( theme, animation: animation, + animate: animate, forceUpdateNonAnimatedTheme: forceUpdateNonAnimatedTheme, ); } @@ -268,24 +309,30 @@ class XThemeController extends ValueNotifier { /// Update the theme to the first theme that matches the device mode. /// If there is no theme that matches the device mode, it will throw an exception. Future updateToDeviceMode({ + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), bool animate = true, - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), bool forceUpdateNonAnimatedTheme = false, }) { - final theme = config.themes + XTheme? theme = config.themes .firstWhereOrNull((element) => element.isDark == isDeviceInDarkMode()); if (theme == null) { + if (config.logThemeChanges) { + logger.error( + 'Could not find any theme that matches the device mode: ${isDeviceInDarkMode()}'); + } throw Exception('Could not find any theme that matches the device mode'); } return updateTo(theme, animation: animation, + animate: animate, forceUpdateNonAnimatedTheme: forceUpdateNonAnimatedTheme); } /// Update the theme to the first theme that matches the given mode. Future updateByThemeMode({ required ThemeMode mode, - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), + bool animate = true, bool forceUpdateNonAnimatedTheme = false, }) { switch (mode) { @@ -300,6 +347,7 @@ class XThemeController extends ValueNotifier { case ThemeMode.dark: return updateToDarkMode( animation: animation, + animate: animate, forceUpdateNonAnimatedTheme: forceUpdateNonAnimatedTheme); } } diff --git a/lib/src/playx_theme.dart b/lib/src/playx_theme.dart index 95a20a4..a90ff43 100644 --- a/lib/src/playx_theme.dart +++ b/lib/src/playx_theme.dart @@ -5,6 +5,8 @@ import 'package:playx_theme/src/model/playx_colors.dart'; import 'package:playx_theme/src/model/playx_theme_animation.dart'; import 'package:playx_theme/src/model/x_theme.dart'; +import '../playx_theme.dart'; + /// Manages the app's theme and provides methods to update it. abstract class PlayxTheme { static XThemeController? _themeControllerInstance; @@ -24,6 +26,19 @@ abstract class PlayxTheme { static Future boot({ required PlayxThemeConfig config, }) async { + PlayxLogger.initLogger(name: 'PLAYX THEME', useColoredFormatter: true); + final logger = PlayxLogger.getLogger('PLAYX THEME')!; + + if (_themeControllerInstance != null) { + logger.w('PlayxTheme is already initialized. ' + 'Calling boot() again will replace the existing instance.'); + await dispose(); + } + if (config.themes.isEmpty) { + logger.e('No themes provided in the configuration.'); + throw Exception('No themes provided in the configuration.'); + } + logger.i('Booting PlayxTheme with ${config.themes.length} themes.'); final controller = XThemeController(config: config); _themeControllerInstance = controller; return controller.boot(); @@ -74,74 +89,81 @@ abstract class PlayxTheme { static List get supportedThemes => _controller.config.themes; /// Updates the app's theme to the provided theme. - /// + /// If [animate] is `true`, the theme change will be animated based on the specified [animation]. + /// If [animate] is `false`, the theme will change instantly. /// You can specify an animation for the theme change using the [animation] parameter. - /// If [animation] is `null`, the theme will change instantly. If [animation] is provided, - /// the theme change will be animated according to the type of animation specified. /// Use [forceUpdateNonAnimatedTheme] to force a theme update without animation if animation is disabled. /// /// Throws an [Exception] if the provided theme is not available in the supported themes. static Future updateTo( XTheme theme, { - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), + bool animate = true, bool forceUpdateNonAnimatedTheme = false, }) => _controller.updateTo( theme, animation: animation, + animate: animate, forceUpdateNonAnimatedTheme: forceUpdateNonAnimatedTheme, ); /// Updates the app's theme to the theme at the specified index. /// /// You can specify an animation for the theme change using the [animation] parameter. - /// If [animation] is `null`, the theme will change instantly. If [animation] is provided, - /// the theme change will be animated according to the type of animation specified. + /// If [animate] is `true`, the theme change will be animated based on the specified [animation]. + /// If [animate] is `false`, the theme will change instantly. /// Use [forceUpdateNonAnimatedTheme] to force a theme update without animation if animation is disabled. /// /// Throws a [RangeError] if the index is out of range. static Future updateByIndex( int index, { - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), + bool animate = true, bool forceUpdateNonAnimatedTheme = false, }) => _controller.updateByIndex( index, animation: animation, + animate: animate, forceUpdateNonAnimatedTheme: forceUpdateNonAnimatedTheme, ); /// Updates the app's theme to the theme with the specified ID. /// /// You can specify an animation for the theme change using the [animation] parameter. - /// If [animation] is `null`, the theme will change instantly. If [animation] is provided, - /// the theme change will be animated according to the type of animation specified. + /// If [animate] is `true`, the theme change will be animated based on the specified [animation]. + /// If [animate] is `false`, the theme will change instantly. /// Use [forceUpdateNonAnimatedTheme] to force a theme update without animation if animation is disabled. /// /// Throws an [Exception] if the ID is not available in the supported themes. static Future updateById( String id, { - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), + bool animate = true, bool forceUpdateNonAnimatedTheme = false, }) => _controller.updateById( id, animation: animation, + animate: animate, forceUpdateNonAnimatedTheme: forceUpdateNonAnimatedTheme, ); /// Updates the app's theme to the next theme in the list. /// /// You can specify an animation for the theme change using the [animation] parameter. - /// If [animation] is `null`, the theme will change instantly. If [animation] is provided, - /// the theme change will be animated according to the type of animation specified. + /// If [animate] is `true`, the theme change will be animated based on the specified [animation]. + /// If [animate] is `false`, the theme will change instantly. /// Use [forceUpdateNonAnimatedTheme] to force a theme update without animation if animation is disabled. static Future next({ - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), + bool animate = true, bool forceUpdateNonAnimatedTheme = false, }) => _controller.nextTheme( animation: animation, + animate: animate, forceUpdateNonAnimatedTheme: forceUpdateNonAnimatedTheme, ); @@ -155,17 +177,19 @@ abstract class PlayxTheme { /// Updates the app's theme to the first light theme available. /// /// You can specify an animation for the theme change using the [animation] parameter. - /// If [animation] is `null`, the theme will change instantly. If [animation] is provided, - /// the theme change will be animated according to the type of animation specified. + /// If [animate] is `true`, the theme change will be animated based on the specified [animation]. + /// If [animate] is `false`, the theme will change instantly. /// Use [forceUpdateNonAnimatedTheme] to force a theme update without animation if animation is disabled. /// /// Throws an [Exception] if no light theme is available in the supported themes. static Future updateToLightMode({ - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), + bool animate = true, bool forceUpdateNonAnimatedTheme = false, }) { return _controller.updateToLightMode( animation: animation, + animate: animate, forceUpdateNonAnimatedTheme: forceUpdateNonAnimatedTheme, ); } @@ -173,17 +197,19 @@ abstract class PlayxTheme { /// Updates the app's theme to the first dark theme available. /// /// You can specify an animation for the theme change using the [animation] parameter. - /// If [animation] is `null`, the theme will change instantly. If [animation] is provided, - /// the theme change will be animated according to the type of animation specified. + /// If [animate] is `true`, the theme change will be animated based on the specified [animation]. + /// If [animate] is `false`, the theme will change instantly. /// Use [forceUpdateNonAnimatedTheme] to force a theme update without animation if animation is disabled. /// /// Throws an [Exception] if no dark theme is available in the supported themes. static Future updateToDarkMode({ - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), + bool animate = true, bool forceUpdateNonAnimatedTheme = false, }) { return _controller.updateToDarkMode( animation: animation, + animate: animate, forceUpdateNonAnimatedTheme: forceUpdateNonAnimatedTheme, ); } @@ -191,17 +217,19 @@ abstract class PlayxTheme { /// Updates the app's theme to the first theme that matches the device's current mode. /// /// You can specify an animation for the theme change using the [animation] parameter. - /// If [animation] is `null`, the theme will change instantly. If [animation] is provided, - /// the theme change will be animated according to the type of animation specified. + /// If [animate] is `true`, the theme change will be animated based on the specified [animation]. + /// If [animate] is `false`, the theme will change instantly. /// Use [forceUpdateNonAnimatedTheme] to force a theme update without animation if animation is disabled. /// /// Throws an [Exception] if no theme matching the device's mode is available in the supported themes. static Future updateToDeviceMode({ - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), + bool animate = true, bool forceUpdateNonAnimatedTheme = false, }) { return _controller.updateToDeviceMode( animation: animation, + animate: animate, forceUpdateNonAnimatedTheme: forceUpdateNonAnimatedTheme, ); } @@ -209,19 +237,21 @@ abstract class PlayxTheme { /// Updates the app's theme to the first theme that matches the given [ThemeMode]. /// /// You can specify an animation for the theme change using the [animation] parameter. - /// If [animation] is `null`, the theme will change instantly. If [animation] is provided, - /// the theme change will be animated according to the type of animation specified. + /// If [animate] is `true`, the theme change will be animated based on the specified [animation]. + /// If [animate] is `false`, the theme will change instantly. /// Use [forceUpdateNonAnimatedTheme] to force a theme update without animation if animation is disabled. /// /// Throws an [Exception] if no theme matching the given [ThemeMode] is found in the [supportedThemes]. static Future updateByThemeMode({ required ThemeMode mode, - PlayxThemeAnimation? animation = const PlayxThemeAnimation.fade(), + PlayxThemeAnimation animation = const PlayxThemeAnimation.fade(), + bool animate = true, bool forceUpdateNonAnimatedTheme = false, }) { return _controller.updateByThemeMode( mode: mode, animation: animation, + animate: animate, forceUpdateNonAnimatedTheme: forceUpdateNonAnimatedTheme, ); } diff --git a/lib/src/utils/build_context_extension.dart b/lib/src/utils/build_context_extension.dart index f9b99a9..62e24f9 100644 --- a/lib/src/utils/build_context_extension.dart +++ b/lib/src/utils/build_context_extension.dart @@ -1,4 +1,5 @@ import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; import 'package:playx_theme/playx_theme.dart'; extension BuildContextExtension on BuildContext { @@ -17,4 +18,16 @@ extension BuildContextExtension on BuildContext { } return colors; } + + /// Returns the [ThemeData] associated with the current context's theme. + ThemeData get themeData { + return xTheme.themeData; + } + + + /// Returns Whether the current theme is a dark theme. + bool get isDarkMode{ + return xTheme.isDark; + } + } diff --git a/lib/src/utils/utils.dart b/lib/src/utils/utils.dart index 8b10283..8142461 100644 --- a/lib/src/utils/utils.dart +++ b/lib/src/utils/utils.dart @@ -6,8 +6,8 @@ ColorScheme getBlendedColorScheme( ColorScheme firstColorScheme, ColorScheme secondColorScheme, ) { - final sourceColor = firstColorScheme.primary.value; - final designColor = secondColorScheme.primary.value; + final sourceColor = firstColorScheme.primary.toARGB32(); + final designColor = secondColorScheme.primary.toARGB32(); final blended = Color(Blend.harmonize(designColor, sourceColor)); return ColorScheme.fromSeed( diff --git a/lib/src/widgets/playx_theme_builder.dart b/lib/src/widgets/playx_theme_builder.dart index 49417a7..642cd2d 100644 --- a/lib/src/widgets/playx_theme_builder.dart +++ b/lib/src/widgets/playx_theme_builder.dart @@ -76,6 +76,7 @@ class _ThemeProviderState extends State @override void dispose() { themeController.updateThemeAnimationController(null); + themeController.dispose(); super.dispose(); } } diff --git a/pubspec.yaml b/pubspec.yaml index 0300add..1e137f5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: playx_theme description: Simplify app theming in Flutter with Playx Theme. Effortlessly switch themes, enjoy smooth animations, and customize color schemes with ease. -version: 1.0.4 +version: 1.1.0 homepage: https://sourcya.io repository: https://github.com/playx-flutter/playx_theme issue_tracker: https://github.com/playx-flutter/playx_theme/issues @@ -12,21 +12,21 @@ topics: - color environment: - sdk: '>=3.4.0 <4.0.0' - flutter: '>=3.22.0' + sdk: '>=3.5.0 <4.0.0' + flutter: '>=3.27.0' dependencies: flutter: sdk: flutter - playx_core: ^0.6.3 - flex_seed_scheme: ^3.4.0 + playx_core: ^0.7.3 + flex_seed_scheme: ^3.5.1 animated_theme_switcher: ^2.0.10 dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^5.0.0 - lints: 5.0.0 + flutter_lints: ^6.0.0 + lints: ^6.0.0 shared_preferences_platform_interface: ^2.4.1