diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml new file mode 100644 index 0000000..00f56a0 --- /dev/null +++ b/.gitea/workflows/test.yaml @@ -0,0 +1,29 @@ +name: Test + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: subosito/flutter-action@v2 + with: + channel: stable + + - name: Activate melos + run: dart pub global activate melos + + - name: Bootstrap workspace + run: dart pub global run melos bootstrap + + - name: Get dependencies + run: dart pub global run melos get + + - name: Run tests + run: dart pub global run melos test \ No newline at end of file diff --git a/.gitignore b/.gitignore index 034b984..4a6b86e 100644 --- a/.gitignore +++ b/.gitignore @@ -279,3 +279,4 @@ fabric.properties # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser +.DS_Store diff --git a/apps/.gitignore b/apps/.gitignore new file mode 100644 index 0000000..3820a95 --- /dev/null +++ b/apps/.gitignore @@ -0,0 +1,45 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.build/ +.buildlog/ +.history +.svn/ +.swiftpm/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ +/coverage/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/apps/.metadata b/apps/.metadata new file mode 100644 index 0000000..9ea3e20 --- /dev/null +++ b/apps/.metadata @@ -0,0 +1,36 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "cc0734ac716fbb8b90f3f9db8020958b1553afa7" + channel: "stable" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + base_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + - platform: android + create_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + base_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + - platform: ios + create_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + base_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + - platform: macos + create_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + base_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/apps/README.md b/apps/README.md new file mode 100644 index 0000000..ef591bf --- /dev/null +++ b/apps/README.md @@ -0,0 +1,17 @@ +# toaster + +Toast-Recorder for Android + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Learn Flutter](https://docs.flutter.dev/get-started/learn-flutter) +- [Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Flutter learning resources](https://docs.flutter.dev/reference/learning-resources) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/apps/analysis_options.yaml b/apps/analysis_options.yaml new file mode 100644 index 0000000..0d29021 --- /dev/null +++ b/apps/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/apps/android/.gitignore b/apps/android/.gitignore new file mode 100644 index 0000000..be3943c --- /dev/null +++ b/apps/android/.gitignore @@ -0,0 +1,14 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java +.cxx/ + +# Remember to never publicly share your keystore. +# See https://flutter.dev/to/reference-keystore +key.properties +**/*.keystore +**/*.jks diff --git a/apps/android/app/build.gradle.kts b/apps/android/app/build.gradle.kts new file mode 100644 index 0000000..6848e14 --- /dev/null +++ b/apps/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 = "org.mars3142.android.toaster" + 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 = "org.mars3142.android.toaster" + // You can update the following values to match your application needs. + // For more information, see: https://flutter.dev/to/review-gradle-config. + minSdk = flutter.minSdkVersion + 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/apps/android/app/src/debug/AndroidManifest.xml b/apps/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/apps/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/apps/android/app/src/main/AndroidManifest.xml b/apps/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..86b6de3 --- /dev/null +++ b/apps/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/android/app/src/main/kotlin/org/mars3142/android/toaster/MainActivity.kt b/apps/android/app/src/main/kotlin/org/mars3142/android/toaster/MainActivity.kt new file mode 100644 index 0000000..023a523 --- /dev/null +++ b/apps/android/app/src/main/kotlin/org/mars3142/android/toaster/MainActivity.kt @@ -0,0 +1,5 @@ +package org.mars3142.android.toaster + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity : FlutterActivity() diff --git a/apps/android/app/src/main/res/drawable-v21/launch_background.xml b/apps/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/apps/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/apps/android/app/src/main/res/drawable/launch_background.xml b/apps/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/apps/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/apps/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/apps/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/apps/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/apps/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/apps/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/apps/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/apps/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/apps/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/apps/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/apps/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/apps/android/app/src/main/res/values-night/styles.xml b/apps/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..06952be --- /dev/null +++ b/apps/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/apps/android/app/src/main/res/values/styles.xml b/apps/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..cb1ef88 --- /dev/null +++ b/apps/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/apps/android/app/src/profile/AndroidManifest.xml b/apps/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/apps/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/apps/android/build.gradle.kts b/apps/android/build.gradle.kts new file mode 100644 index 0000000..dbee657 --- /dev/null +++ b/apps/android/build.gradle.kts @@ -0,0 +1,24 @@ +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/apps/android/gradle.properties b/apps/android/gradle.properties new file mode 100644 index 0000000..fbee1d8 --- /dev/null +++ b/apps/android/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError +android.useAndroidX=true diff --git a/apps/android/gradle/wrapper/gradle-wrapper.properties b/apps/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..e4ef43f --- /dev/null +++ b/apps/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip diff --git a/apps/android/settings.gradle.kts b/apps/android/settings.gradle.kts new file mode 100644 index 0000000..ca7fe06 --- /dev/null +++ b/apps/android/settings.gradle.kts @@ -0,0 +1,26 @@ +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.11.1" apply false + id("org.jetbrains.kotlin.android") version "2.2.20" apply false +} + +include(":app") diff --git a/apps/ios/.gitignore b/apps/ios/.gitignore new file mode 100644 index 0000000..7a7f987 --- /dev/null +++ b/apps/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/apps/ios/Flutter/AppFrameworkInfo.plist b/apps/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..391a902 --- /dev/null +++ b/apps/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + + diff --git a/apps/ios/Flutter/Debug.xcconfig b/apps/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..ec97fc6 --- /dev/null +++ b/apps/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/apps/ios/Flutter/Release.xcconfig b/apps/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..c4855bf --- /dev/null +++ b/apps/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/apps/ios/Podfile b/apps/ios/Podfile new file mode 100644 index 0000000..620e46e --- /dev/null +++ b/apps/ios/Podfile @@ -0,0 +1,43 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '13.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/apps/ios/Runner.xcodeproj/project.pbxproj b/apps/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..d589c98 --- /dev/null +++ b/apps/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,626 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 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 */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* 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 = ""; }; + 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 = ""; }; + 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 = ""; }; + 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.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; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 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 = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 331C8082294A63A400263BE5 /* RunnerTests */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C807D294A63A400263BE5 /* Sources */, + 331C807F294A63A400263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C8086294A63A400263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C8080294A63A400263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 97C146ED1CF9000F007C117D; + }; + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + 331C8080294A63A400263BE5 /* RunnerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C807F294A63A400263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C807D294A63A400263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 55PNJ85CXL; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = org.mars3142.android.toaster; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 331C8088294A63A400263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = org.mars3142.android.toaster.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 331C8089294A63A400263BE5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = org.mars3142.android.toaster.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 331C808A294A63A400263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = org.mars3142.android.toaster.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 55PNJ85CXL; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = org.mars3142.android.toaster; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 55PNJ85CXL; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = org.mars3142.android.toaster; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C8088294A63A400263BE5 /* Debug */, + 331C8089294A63A400263BE5 /* Release */, + 331C808A294A63A400263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/apps/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/apps/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/apps/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/apps/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/apps/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/apps/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/apps/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/apps/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/apps/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/apps/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/apps/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..e3773d4 --- /dev/null +++ b/apps/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/ios/Runner.xcworkspace/contents.xcworkspacedata b/apps/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/apps/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/apps/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/apps/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/apps/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/apps/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/apps/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/apps/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/apps/ios/Runner/AppDelegate.swift b/apps/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..c30b367 --- /dev/null +++ b/apps/ios/Runner/AppDelegate.swift @@ -0,0 +1,16 @@ +import Flutter +import UIKit + +@main +@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } + + func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) { + GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry) + } +} diff --git a/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..dc9ada4 Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..7353c41 Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..797d452 Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..6ed2d93 Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cd7b00 Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..fe73094 Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..321773c Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..797d452 Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..502f463 Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..0ec3034 Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..0ec3034 Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..e9f5fea Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..84ac32a Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..8953cba Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..0467bf1 Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/apps/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/apps/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/apps/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/apps/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/apps/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/apps/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/apps/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/apps/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/apps/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/apps/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/apps/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/apps/ios/Runner/Base.lproj/LaunchScreen.storyboard b/apps/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/apps/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/ios/Runner/Base.lproj/Main.storyboard b/apps/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/apps/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/ios/Runner/Info.plist b/apps/ios/Runner/Info.plist new file mode 100644 index 0000000..09f8149 --- /dev/null +++ b/apps/ios/Runner/Info.plist @@ -0,0 +1,70 @@ + + + + + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Toaster + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + toaster + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneClassName + UIWindowScene + UISceneConfigurationName + flutter + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/apps/ios/Runner/Runner-Bridging-Header.h b/apps/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/apps/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/apps/ios/Runner/SceneDelegate.swift b/apps/ios/Runner/SceneDelegate.swift new file mode 100644 index 0000000..b9ce8ea --- /dev/null +++ b/apps/ios/Runner/SceneDelegate.swift @@ -0,0 +1,6 @@ +import Flutter +import UIKit + +class SceneDelegate: FlutterSceneDelegate { + +} diff --git a/apps/ios/RunnerTests/RunnerTests.swift b/apps/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..86a7c3b --- /dev/null +++ b/apps/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Flutter +import UIKit +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/apps/lib/main.dart b/apps/lib/main.dart new file mode 100644 index 0000000..3b8f8e8 --- /dev/null +++ b/apps/lib/main.dart @@ -0,0 +1,106 @@ +import 'package:toaster_ui/toaster_ui.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: AppTheme.toaster, + home: const MyHomePage(title: 'Flutter Demo Home Page'), + ); + } +} + +class MyHomePage extends StatefulWidget { + const MyHomePage({super.key, required this.title}); + + // This widget is the home page of your application. It is stateful, meaning + // that it has a State object (defined below) that contains fields that affect + // how it looks. + + // This class is the configuration for the state. It holds the values (in this + // case the title) provided by the parent (in this case the App widget) and + // used by the build method of the State. Fields in a Widget subclass are + // always marked "final". + + final String title; + + @override + State createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + int _counter = 0; + + void _incrementCounter() { + setState(() { + // This call to setState tells the Flutter framework that something has + // changed in this State, which causes it to rerun the build method below + // so that the display can reflect the updated values. If we changed + // _counter without calling setState(), then the build method would not be + // called again, and so nothing would appear to happen. + _counter++; + }); + } + + @override + Widget build(BuildContext context) { + // This method is rerun every time setState is called, for instance as done + // by the _incrementCounter method above. + // + // The Flutter framework has been optimized to make rerunning build methods + // fast, so that you can just rebuild anything that needs updating rather + // than having to individually change instances of widgets. + return Scaffold( + appBar: AppBar( + // TRY THIS: Try changing the color here to a specific color (to + // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar + // change color while the other colors stay the same. + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: Text(widget.title), + ), + body: Center( + // Center is a layout widget. It takes a single child and positions it + // in the middle of the parent. + child: Column( + // Column is also a layout widget. It takes a list of children and + // arranges them vertically. By default, it sizes itself to fit its + // children horizontally, and tries to be as tall as its parent. + // + // Column has various properties to control how it sizes itself and + // how it positions its children. Here we use mainAxisAlignment to + // center the children vertically; the main axis here is the vertical + // axis because Columns are vertical (the cross axis would be + // horizontal). + // + // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" + // action in the IDE, or press "p" in the console), to see the + // wireframe for each widget. + mainAxisAlignment: .center, + children: [ + AppButton(onPressed: () {}, child: Text('Peter')), + const Text('You have pushed the button this many times:'), + Text( + '$_counter', + style: Theme.of(context).textTheme.headlineMedium, + ), + ], + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: _incrementCounter, + tooltip: 'Increment', + child: const Icon(Icons.add), + ), + ); + } +} diff --git a/apps/macos/.gitignore b/apps/macos/.gitignore new file mode 100644 index 0000000..746adbb --- /dev/null +++ b/apps/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/apps/macos/Flutter/Flutter-Debug.xcconfig b/apps/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 0000000..4b81f9b --- /dev/null +++ b/apps/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/apps/macos/Flutter/Flutter-Release.xcconfig b/apps/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 0000000..5caa9d1 --- /dev/null +++ b/apps/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/apps/macos/Podfile b/apps/macos/Podfile new file mode 100644 index 0000000..ff5ddb3 --- /dev/null +++ b/apps/macos/Podfile @@ -0,0 +1,42 @@ +platform :osx, '10.15' + +# 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/apps/macos/Runner.xcodeproj/project.pbxproj b/apps/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..63bac48 --- /dev/null +++ b/apps/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,801 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 27F2FE3051B2B455D904DBE8 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DE0B230E1106A25968200879 /* Pods_RunnerTests.framework */; }; + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; }; + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + 92BFDFE347E08FA0E2C36B59 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 344C15AFF67B9867C7B91384 /* Pods_Runner.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC10EC2044A3C60003C045; + remoteInfo = Runner; + }; + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1964C64ECDB2025A742B9DAD /* 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 = ""; }; + 2DF70111D99918037A049AC5 /* 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 = ""; }; + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* toaster.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = toaster.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 344C15AFF67B9867C7B91384 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 68837A566BCA455992BEBA5C /* 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 = ""; }; + 695090E5ADADA0AFB2F4EA0E /* 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 = ""; }; + 7A0D600308FFB605B8AA1123 /* 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 = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + D74C7455B78DC3F2A150EA1E /* 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 = ""; }; + DE0B230E1106A25968200879 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 331C80D2294CF70F00263BE5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 27F2FE3051B2B455D904DBE8 /* Pods_RunnerTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 92BFDFE347E08FA0E2C36B59 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 15934F6019FCFB23934940C8 /* Pods */ = { + isa = PBXGroup; + children = ( + D74C7455B78DC3F2A150EA1E /* Pods-Runner.debug.xcconfig */, + 1964C64ECDB2025A742B9DAD /* Pods-Runner.release.xcconfig */, + 2DF70111D99918037A049AC5 /* Pods-Runner.profile.xcconfig */, + 68837A566BCA455992BEBA5C /* Pods-RunnerTests.debug.xcconfig */, + 695090E5ADADA0AFB2F4EA0E /* Pods-RunnerTests.release.xcconfig */, + 7A0D600308FFB605B8AA1123 /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + 331C80D6294CF71000263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C80D7294CF71000263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 331C80D6294CF71000263BE5 /* RunnerTests */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + 15934F6019FCFB23934940C8 /* Pods */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* toaster.app */, + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 344C15AFF67B9867C7B91384 /* Pods_Runner.framework */, + DE0B230E1106A25968200879 /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C80D4294CF70F00263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + B82BE88C0315CDD61410DC0D /* [CP] Check Pods Manifest.lock */, + 331C80D1294CF70F00263BE5 /* Sources */, + 331C80D2294CF70F00263BE5 /* Frameworks */, + 331C80D3294CF70F00263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C80DA294CF71000263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + EFB0F1348D4999A5E318EFCC /* [CP] Check Pods Manifest.lock */, + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + 659FB32D23A5F9B36108379B /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* toaster.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C80D4294CF70F00263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 33CC10EC2044A3C60003C045; + }; + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 331C80D4294CF70F00263BE5 /* RunnerTests */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C80D3294CF70F00263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; + 659FB32D23A5F9B36108379B /* [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; + }; + B82BE88C0315CDD61410DC0D /* [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; + }; + EFB0F1348D4999A5E318EFCC /* [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; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C80D1294CF70F00263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC10EC2044A3C60003C045 /* Runner */; + targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */; + }; + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 331C80DB294CF71000263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 68837A566BCA455992BEBA5C /* Pods-RunnerTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = org.mars3142.android.toaster.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/toaster.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/toaster"; + }; + name = Debug; + }; + 331C80DC294CF71000263BE5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 695090E5ADADA0AFB2F4EA0E /* Pods-RunnerTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = org.mars3142.android.toaster.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/toaster.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/toaster"; + }; + name = Release; + }; + 331C80DD294CF71000263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7A0D600308FFB605B8AA1123 /* Pods-RunnerTests.profile.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = org.mars3142.android.toaster.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/toaster.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/toaster"; + }; + name = Profile; + }; + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C80DB294CF71000263BE5 /* Debug */, + 331C80DC294CF71000263BE5 /* Release */, + 331C80DD294CF71000263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/apps/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/apps/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/apps/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/apps/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/apps/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..4ee01b8 --- /dev/null +++ b/apps/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/macos/Runner.xcworkspace/contents.xcworkspacedata b/apps/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/apps/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/apps/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/apps/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/apps/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/apps/macos/Runner/AppDelegate.swift b/apps/macos/Runner/AppDelegate.swift new file mode 100644 index 0000000..b3c1761 --- /dev/null +++ b/apps/macos/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import Cocoa +import FlutterMacOS + +@main +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } + + override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } +} diff --git a/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a2ec33f --- /dev/null +++ b/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 0000000..82b6f9d Binary files /dev/null and b/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 0000000..13b35eb Binary files /dev/null and b/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 0000000..0a3f5fa Binary files /dev/null and b/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 0000000..bdb5722 Binary files /dev/null and b/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 0000000..f083318 Binary files /dev/null and b/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 0000000..326c0e7 Binary files /dev/null and b/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 0000000..2f1632c Binary files /dev/null and b/apps/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/apps/macos/Runner/Base.lproj/MainMenu.xib b/apps/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 0000000..80e867a --- /dev/null +++ b/apps/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/macos/Runner/Configs/AppInfo.xcconfig b/apps/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 0000000..ce3ea3d --- /dev/null +++ b/apps/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = toaster + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = org.mars3142.android.toaster + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2026 org.mars3142.android. All rights reserved. diff --git a/apps/macos/Runner/Configs/Debug.xcconfig b/apps/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 0000000..36b0fd9 --- /dev/null +++ b/apps/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/apps/macos/Runner/Configs/Release.xcconfig b/apps/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 0000000..dff4f49 --- /dev/null +++ b/apps/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/apps/macos/Runner/Configs/Warnings.xcconfig b/apps/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 0000000..42bcbf4 --- /dev/null +++ b/apps/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/apps/macos/Runner/DebugProfile.entitlements b/apps/macos/Runner/DebugProfile.entitlements new file mode 100644 index 0000000..dddb8a3 --- /dev/null +++ b/apps/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/apps/macos/Runner/Info.plist b/apps/macos/Runner/Info.plist new file mode 100644 index 0000000..4789daa --- /dev/null +++ b/apps/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/apps/macos/Runner/MainFlutterWindow.swift b/apps/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 0000000..3cc05eb --- /dev/null +++ b/apps/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/apps/macos/Runner/Release.entitlements b/apps/macos/Runner/Release.entitlements new file mode 100644 index 0000000..852fa1a --- /dev/null +++ b/apps/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/apps/macos/RunnerTests/RunnerTests.swift b/apps/macos/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..61f3bd1 --- /dev/null +++ b/apps/macos/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Cocoa +import FlutterMacOS +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/apps/pubspec.yaml b/apps/pubspec.yaml new file mode 100644 index 0000000..b7e9937 --- /dev/null +++ b/apps/pubspec.yaml @@ -0,0 +1,96 @@ +name: toaster +description: "Toast-Recorder for Android" +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +# In Windows, build-name is used as the major, minor, and patch parts +# of the product and file versions while build-number is used as the build suffix. +version: 1.0.0+1 + +environment: + sdk: ^3.11.5 + +resolution: workspace + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.8 + + toaster_utils: + path: ../plugins/toaster_utils/toaster_utils + toaster_ui: + path: ../packages/toaster_ui + +dev_dependencies: + flutter_test: + sdk: flutter + + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + flutter_lints: ^6.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/to/resolution-aware-images + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/to/asset-from-package + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/to/font-from-package diff --git a/apps/test/widget_test.dart b/apps/test/widget_test.dart new file mode 100644 index 0000000..db52ec6 --- /dev/null +++ b/apps/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility in the flutter_test package. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:toaster/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/packages/toaster_ui/.github/ISSUE_TEMPLATE/bug_report.md b/packages/toaster_ui/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..50a4c7b --- /dev/null +++ b/packages/toaster_ui/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,29 @@ +--- +name: Bug Report +about: Create a report to help us improve +title: "fix: " +labels: bug +--- + +**Description** + +A clear and concise description of what the bug is. + +**Steps To Reproduce** + +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected Behavior** + +A clear and concise description of what you expected to happen. + +**Screenshots** + +If applicable, add screenshots to help explain your problem. + +**Additional Context** + +Add any other context about the problem here. diff --git a/packages/toaster_ui/.github/ISSUE_TEMPLATE/build.md b/packages/toaster_ui/.github/ISSUE_TEMPLATE/build.md new file mode 100644 index 0000000..0cf8e62 --- /dev/null +++ b/packages/toaster_ui/.github/ISSUE_TEMPLATE/build.md @@ -0,0 +1,14 @@ +--- +name: Build System +about: Changes that affect the build system or external dependencies +title: "build: " +labels: build +--- + +**Description** + +Describe what changes need to be done to the build system and why. + +**Requirements** + +- [ ] The build system is passing diff --git a/packages/toaster_ui/.github/ISSUE_TEMPLATE/chore.md b/packages/toaster_ui/.github/ISSUE_TEMPLATE/chore.md new file mode 100644 index 0000000..498ebfd --- /dev/null +++ b/packages/toaster_ui/.github/ISSUE_TEMPLATE/chore.md @@ -0,0 +1,14 @@ +--- +name: Chore +about: Other changes that don't modify src or test files +title: "chore: " +labels: chore +--- + +**Description** + +Clearly describe what change is needed and why. If this changes code then please use another issue type. + +**Requirements** + +- [ ] No functional changes to the code diff --git a/packages/toaster_ui/.github/ISSUE_TEMPLATE/ci.md b/packages/toaster_ui/.github/ISSUE_TEMPLATE/ci.md new file mode 100644 index 0000000..fa2dd9e --- /dev/null +++ b/packages/toaster_ui/.github/ISSUE_TEMPLATE/ci.md @@ -0,0 +1,14 @@ +--- +name: Continuous Integration +about: Changes to the CI configuration files and scripts +title: "ci: " +labels: ci +--- + +**Description** + +Describe what changes need to be done to the ci/cd system and why. + +**Requirements** + +- [ ] The ci system is passing diff --git a/packages/toaster_ui/.github/ISSUE_TEMPLATE/config.yml b/packages/toaster_ui/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3ba13e0 --- /dev/null +++ b/packages/toaster_ui/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/packages/toaster_ui/.github/ISSUE_TEMPLATE/documentation.md b/packages/toaster_ui/.github/ISSUE_TEMPLATE/documentation.md new file mode 100644 index 0000000..f494a4d --- /dev/null +++ b/packages/toaster_ui/.github/ISSUE_TEMPLATE/documentation.md @@ -0,0 +1,14 @@ +--- +name: Documentation +about: Improve the documentation so all collaborators have a common understanding +title: "docs: " +labels: documentation +--- + +**Description** + +Clearly describe what documentation you are looking to add or improve. + +**Requirements** + +- [ ] Requirements go here diff --git a/packages/toaster_ui/.github/ISSUE_TEMPLATE/feature_request.md b/packages/toaster_ui/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..ddd2fcc --- /dev/null +++ b/packages/toaster_ui/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,18 @@ +--- +name: Feature Request +about: A new feature to be added to the project +title: "feat: " +labels: feature +--- + +**Description** + +Clearly describe what you are looking to add. The more context the better. + +**Requirements** + +- [ ] Checklist of requirements to be fulfilled + +**Additional Context** + +Add any other context or screenshots about the feature request go here. diff --git a/packages/toaster_ui/.github/ISSUE_TEMPLATE/performance.md b/packages/toaster_ui/.github/ISSUE_TEMPLATE/performance.md new file mode 100644 index 0000000..699b8d4 --- /dev/null +++ b/packages/toaster_ui/.github/ISSUE_TEMPLATE/performance.md @@ -0,0 +1,14 @@ +--- +name: Performance Update +about: A code change that improves performance +title: "perf: " +labels: performance +--- + +**Description** + +Clearly describe what code needs to be changed and what the performance impact is going to be. Bonus point's if you can tie this directly to user experience. + +**Requirements** + +- [ ] There is no drop in test coverage. diff --git a/packages/toaster_ui/.github/ISSUE_TEMPLATE/refactor.md b/packages/toaster_ui/.github/ISSUE_TEMPLATE/refactor.md new file mode 100644 index 0000000..1626c57 --- /dev/null +++ b/packages/toaster_ui/.github/ISSUE_TEMPLATE/refactor.md @@ -0,0 +1,14 @@ +--- +name: Refactor +about: A code change that neither fixes a bug nor adds a feature +title: "refactor: " +labels: refactor +--- + +**Description** + +Clearly describe what needs to be refactored and why. Please provide links to related issues (bugs or upcoming features) in order to help prioritize. + +**Requirements** + +- [ ] There is no drop in test coverage. diff --git a/packages/toaster_ui/.github/ISSUE_TEMPLATE/revert.md b/packages/toaster_ui/.github/ISSUE_TEMPLATE/revert.md new file mode 100644 index 0000000..9d121dc --- /dev/null +++ b/packages/toaster_ui/.github/ISSUE_TEMPLATE/revert.md @@ -0,0 +1,16 @@ +--- +name: Revert Commit +about: Reverts a previous commit +title: "revert: " +labels: revert +--- + +**Description** + +Provide a link to a PR/Commit that you are looking to revert and why. + +**Requirements** + +- [ ] Change has been reverted +- [ ] No change in test coverage has happened +- [ ] A new ticket is created for any follow on work that needs to happen diff --git a/packages/toaster_ui/.github/ISSUE_TEMPLATE/style.md b/packages/toaster_ui/.github/ISSUE_TEMPLATE/style.md new file mode 100644 index 0000000..02244a7 --- /dev/null +++ b/packages/toaster_ui/.github/ISSUE_TEMPLATE/style.md @@ -0,0 +1,14 @@ +--- +name: Style Changes +about: Changes that do not affect the meaning of the code (white space, formatting, missing semi-colons, etc) +title: "style: " +labels: style +--- + +**Description** + +Clearly describe what you are looking to change and why. + +**Requirements** + +- [ ] There is no drop in test coverage. diff --git a/packages/toaster_ui/.github/ISSUE_TEMPLATE/test.md b/packages/toaster_ui/.github/ISSUE_TEMPLATE/test.md new file mode 100644 index 0000000..431a7ea --- /dev/null +++ b/packages/toaster_ui/.github/ISSUE_TEMPLATE/test.md @@ -0,0 +1,14 @@ +--- +name: Test +about: Adding missing tests or correcting existing tests +title: "test: " +labels: test +--- + +**Description** + +List out the tests that need to be added or changed. Please also include any information as to why this was not covered in the past. + +**Requirements** + +- [ ] There is no drop in test coverage. diff --git a/packages/toaster_ui/.github/PULL_REQUEST_TEMPLATE.md b/packages/toaster_ui/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..b05836d --- /dev/null +++ b/packages/toaster_ui/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,28 @@ + + +## Status + +**READY/IN DEVELOPMENT/HOLD** + +## Description + + + +## Type of Change + + + +- [ ] ✨ New feature (non-breaking change which adds functionality) +- [ ] 🛠️ Bug fix (non-breaking change which fixes an issue) +- [ ] ❌ Breaking change (fix or feature that would cause existing functionality to change) +- [ ] 🧹 Code refactor +- [ ] ✅ Build configuration change +- [ ] 📝 Documentation +- [ ] 🗑️ Chore +- [ ] 🧪 Test diff --git a/packages/toaster_ui/.github/cspell.json b/packages/toaster_ui/.github/cspell.json new file mode 100644 index 0000000..b4c9d63 --- /dev/null +++ b/packages/toaster_ui/.github/cspell.json @@ -0,0 +1,25 @@ +{ + "version": "0.2", + "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json", + "dictionaries": ["vgv_allowed", "vgv_forbidden"], + "dictionaryDefinitions": [ + { + "name": "vgv_allowed", + "path": "https://raw.githubusercontent.com/verygoodopensource/very_good_dictionaries/main/allowed.txt", + "description": "Allowed VGV Spellings" + }, + { + "name": "vgv_forbidden", + "path": "https://raw.githubusercontent.com/verygoodopensource/very_good_dictionaries/main/forbidden.txt", + "description": "Forbidden VGV Spellings" + } + ], + "useGitignore": true, + "words": [ + "toaster_ui", + "lerp", + "xxlg", + "widgetbook", + "Widgetbook" + ] +} diff --git a/packages/toaster_ui/.github/dependabot.yaml b/packages/toaster_ui/.github/dependabot.yaml new file mode 100644 index 0000000..63b035c --- /dev/null +++ b/packages/toaster_ui/.github/dependabot.yaml @@ -0,0 +1,11 @@ +version: 2 +enable-beta-ecosystems: true +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + - package-ecosystem: "pub" + directory: "/" + schedule: + interval: "daily" diff --git a/packages/toaster_ui/.github/workflows/license_check.yaml b/packages/toaster_ui/.github/workflows/license_check.yaml new file mode 100644 index 0000000..ce6acfc --- /dev/null +++ b/packages/toaster_ui/.github/workflows/license_check.yaml @@ -0,0 +1,25 @@ +name: license_check + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + branches: + - main + paths: + - "pubspec.yaml" + - ".github/workflows/license_check.yaml" + push: + branches: + - main + paths: + - "pubspec.yaml" + - ".github/workflows/license_check.yaml" + +jobs: + license_check: + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/license_check.yml@v1 + with: + allowed: "MIT,BSD-3-Clause,BSD-2-Clause,Apache-2.0" diff --git a/packages/toaster_ui/.github/workflows/main.yaml b/packages/toaster_ui/.github/workflows/main.yaml new file mode 100644 index 0000000..bc3a1c7 --- /dev/null +++ b/packages/toaster_ui/.github/workflows/main.yaml @@ -0,0 +1,25 @@ +name: ci + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + branches: + - main + +jobs: + semantic_pull_request: + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/semantic_pull_request.yml@v1 + + spell-check: + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/spell_check.yml@v1 + with: + includes: "**/*.md" + modified_files_only: false + + build: + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1 + with: + flutter_version: "3.41.x" diff --git a/packages/toaster_ui/.gitignore b/packages/toaster_ui/.gitignore new file mode 100644 index 0000000..2c0a96a --- /dev/null +++ b/packages/toaster_ui/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# VSCode related +.vscode/* + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ +pubspec.lock + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Test related +coverage diff --git a/packages/toaster_ui/CHANGELOG.md b/packages/toaster_ui/CHANGELOG.md new file mode 100644 index 0000000..bec7d4c --- /dev/null +++ b/packages/toaster_ui/CHANGELOG.md @@ -0,0 +1,3 @@ +# 0.1.0+1 + +- Initial release. diff --git a/packages/toaster_ui/LICENSE b/packages/toaster_ui/LICENSE new file mode 100644 index 0000000..3cef8a0 --- /dev/null +++ b/packages/toaster_ui/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/toaster_ui/README.md b/packages/toaster_ui/README.md new file mode 100644 index 0000000..8fe3347 --- /dev/null +++ b/packages/toaster_ui/README.md @@ -0,0 +1,112 @@ +# Toaster Ui + +[![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] +[![Powered by Mason](https://img.shields.io/endpoint?url=https%3A%2F%2Ftinyurl.com%2Fmason-badge)](https://github.com/felangel/mason) +[![License: MIT][license_badge]][license_link] + +A Very Good Project created by Very Good CLI. + +## Installation 💻 + +**❗ In order to start using Toaster Ui you must have the [Flutter SDK][flutter_install_link] installed on your machine.** + +Install via `flutter pub add`: + +```sh +dart pub add toaster_ui +``` + +--- + +## Features ✨ + +- **ThemeExtension-based theming** — light and dark theme variants with custom color and spacing tokens via `ThemeExtension` +- **Custom color tokens** — semantic colors for success, warning, and info states via `AppColors` +- **Spacing scale** — consistent spacing tokens from xxs to xxlg via `AppSpacing` +- **BuildContext extensions** — shorthand `context.appColors` and `context.appSpacing` +- **Example widget** — `AppButton` composing Material's `FilledButton` and `OutlinedButton` with app-specific sizing + +## Usage 🚀 + +Wrap your app with the theme: + +```dart +import 'package:toaster_ui/toaster_ui.dart'; + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + theme: AppTheme.light, + darkTheme: AppTheme.dark, + home: const MyHomePage(), + ); + } +} +``` + +Use widgets and tokens in your app: + +```dart +AppButton( + onPressed: () {}, + child: const Text('Click me'), +); +``` + +Access custom tokens via context extensions: + +```dart +final colors = context.appColors; +final spacing = context.appSpacing; +``` + +--- + +## Continuous Integration 🤖 + +Toaster Ui comes with a built-in [GitHub Actions workflow][github_actions_link] powered by [Very Good Workflows][very_good_workflows_link] but you can also add your preferred CI/CD solution. + +Out of the box, on each pull request and push, the CI `formats`, `lints`, and `tests` the code. This ensures the code remains consistent and behaves correctly as you add functionality or make changes. The project uses [Very Good Analysis][very_good_analysis_link] for a strict set of analysis options used by our team. Code coverage is enforced using the [Very Good Workflows][very_good_coverage_link]. + +--- + +## Running Tests 🧪 + +For first time users, install the [very_good_cli][very_good_cli_link]: + +```sh +dart pub global activate very_good_cli +``` + +To run all unit tests: + +```sh +very_good test --coverage +``` + +To view the generated coverage report you can use [lcov](https://github.com/linux-test-project/lcov). + +```sh +# Generate Coverage Report +genhtml coverage/lcov.info -o coverage/ + +# Open Coverage Report +open coverage/index.html +``` + +[flutter_install_link]: https://docs.flutter.dev/get-started/install +[github_actions_link]: https://docs.github.com/en/actions/learn-github-actions +[license_badge]: https://img.shields.io/badge/license-MIT-blue.svg +[license_link]: https://opensource.org/licenses/MIT +[logo_black]: https://raw.githubusercontent.com/VGVentures/very_good_brand/main/styles/README/vgv_logo_black.png#gh-light-mode-only +[logo_white]: https://raw.githubusercontent.com/VGVentures/very_good_brand/main/styles/README/vgv_logo_white.png#gh-dark-mode-only +[mason_link]: https://github.com/felangel/mason +[very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg +[very_good_analysis_link]: https://pub.dev/packages/very_good_analysis +[very_good_cli_link]: https://pub.dev/packages/very_good_cli +[very_good_coverage_link]: https://github.com/marketplace/actions/very-good-coverage +[very_good_ventures_link]: https://verygood.ventures +[very_good_ventures_link_light]: https://verygood.ventures#gh-light-mode-only +[very_good_ventures_link_dark]: https://verygood.ventures#gh-dark-mode-only +[very_good_workflows_link]: https://github.com/VeryGoodOpenSource/very_good_workflows diff --git a/packages/toaster_ui/analysis_options.yaml b/packages/toaster_ui/analysis_options.yaml new file mode 100644 index 0000000..8cf0c27 --- /dev/null +++ b/packages/toaster_ui/analysis_options.yaml @@ -0,0 +1,5 @@ +include: package:very_good_analysis/analysis_options.yaml + +analyzer: + exclude: + - "widgetbook/**" diff --git a/packages/toaster_ui/coverage_badge.svg b/packages/toaster_ui/coverage_badge.svg new file mode 100644 index 0000000..499e98c --- /dev/null +++ b/packages/toaster_ui/coverage_badge.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + coverage + coverage + 100% + 100% + + diff --git a/packages/toaster_ui/lib/src/extensions/build_context_extensions.dart b/packages/toaster_ui/lib/src/extensions/build_context_extensions.dart new file mode 100644 index 0000000..e5ac3dc --- /dev/null +++ b/packages/toaster_ui/lib/src/extensions/build_context_extensions.dart @@ -0,0 +1,10 @@ +import 'package:toaster_ui/toaster_ui.dart'; + +/// Extension on [BuildContext] for easy access to custom theme tokens. +extension AppThemeBuildContext on BuildContext { + /// Returns the [AppColors] from the current theme. + AppColors get appColors => Theme.of(this).extension()!; + + /// Returns the [AppSpacing] from the current theme. + AppSpacing get appSpacing => Theme.of(this).extension()!; +} diff --git a/packages/toaster_ui/lib/src/theme/app_colors.dart b/packages/toaster_ui/lib/src/theme/app_colors.dart new file mode 100644 index 0000000..294bf59 --- /dev/null +++ b/packages/toaster_ui/lib/src/theme/app_colors.dart @@ -0,0 +1,83 @@ +import 'package:toaster_ui/toaster_ui.dart'; + +/// {@template app_colors} +/// Custom color tokens beyond Material's [ColorScheme]. +/// +/// Provides semantic colors for success, warning, and info states +/// along with their on-color variants. +/// {@endtemplate} +class AppColors extends ThemeExtension { + /// {@macro app_colors} + const AppColors({ + required this.success, + required this.onSuccess, + required this.warning, + required this.onWarning, + required this.info, + required this.onInfo, + required this.neutral, + required this.onNeutral, + }); + + /// The color used for success states. + final Color success; + + /// The color used for content on top of [success]. + final Color onSuccess; + + /// The color used for warning states. + final Color warning; + + /// The color used for content on top of [warning]. + final Color onWarning; + + /// The color used for informational states. + final Color info; + + /// The color used for content on top of [info]. + final Color onInfo; + + /// + final Color neutral; + + /// + final Color onNeutral; + + @override + AppColors copyWith({ + Color? success, + Color? onSuccess, + Color? warning, + Color? onWarning, + Color? info, + Color? onInfo, + Color? neutral, + Color? onNeutral, + }) { + return AppColors( + success: success ?? this.success, + onSuccess: onSuccess ?? this.onSuccess, + warning: warning ?? this.warning, + onWarning: onWarning ?? this.onWarning, + info: info ?? this.info, + onInfo: onInfo ?? this.onInfo, + neutral: neutral ?? this.neutral, + onNeutral: onNeutral ?? this.onNeutral, + ); + } + + @override + AppColors lerp(AppColors? other, double t) { + if (other is! AppColors) return this; + return AppColors( + success: Color.lerp(success, other.success, t)!, + onSuccess: Color.lerp(onSuccess, other.onSuccess, t)!, + warning: Color.lerp(warning, other.warning, t)!, + onWarning: Color.lerp(onWarning, other.onWarning, t)!, + info: Color.lerp(info, other.info, t)!, + onInfo: Color.lerp(onInfo, other.onInfo, t)!, + neutral: Color.lerp(neutral, other.neutral, t)!, + onNeutral: Color.lerp(onNeutral, other.onNeutral, t)!, + ); + } +} diff --git a/packages/toaster_ui/lib/src/theme/app_spacing.dart b/packages/toaster_ui/lib/src/theme/app_spacing.dart new file mode 100644 index 0000000..9cf6ae5 --- /dev/null +++ b/packages/toaster_ui/lib/src/theme/app_spacing.dart @@ -0,0 +1,75 @@ +import 'dart:ui'; + +import 'package:toaster_ui/toaster_ui.dart'; + +/// {@template app_spacing} +/// Spacing scale tokens for consistent layout throughout the app. +/// {@endtemplate} +class AppSpacing extends ThemeExtension { + /// {@macro app_spacing} + const AppSpacing({ + this.xxs = 4, + this.xs = 8, + this.sm = 12, + this.md = 16, + this.lg = 24, + this.xlg = 32, + this.xxlg = 48, + }); + + /// Extra extra small spacing: 4px. + final double xxs; + + /// Extra small spacing: 8px. + final double xs; + + /// Small spacing: 12px. + final double sm; + + /// Medium spacing: 16px. + final double md; + + /// Large spacing: 24px. + final double lg; + + /// Extra large spacing: 32px. + final double xlg; + + /// Extra extra large spacing: 48px. + final double xxlg; + + @override + AppSpacing copyWith({ + double? xxs, + double? xs, + double? sm, + double? md, + double? lg, + double? xlg, + double? xxlg, + }) { + return AppSpacing( + xxs: xxs ?? this.xxs, + xs: xs ?? this.xs, + sm: sm ?? this.sm, + md: md ?? this.md, + lg: lg ?? this.lg, + xlg: xlg ?? this.xlg, + xxlg: xxlg ?? this.xxlg, + ); + } + + @override + AppSpacing lerp(AppSpacing? other, double t) { + if (other is! AppSpacing) return this; + return AppSpacing( + xxs: lerpDouble(xxs, other.xxs, t)!, + xs: lerpDouble(xs, other.xs, t)!, + sm: lerpDouble(sm, other.sm, t)!, + md: lerpDouble(md, other.md, t)!, + lg: lerpDouble(lg, other.lg, t)!, + xlg: lerpDouble(xlg, other.xlg, t)!, + xxlg: lerpDouble(xxlg, other.xxlg, t)!, + ); + } +} diff --git a/packages/toaster_ui/lib/src/theme/app_theme.dart b/packages/toaster_ui/lib/src/theme/app_theme.dart new file mode 100644 index 0000000..489829b --- /dev/null +++ b/packages/toaster_ui/lib/src/theme/app_theme.dart @@ -0,0 +1,31 @@ +import 'package:toaster_ui/toaster_ui.dart'; + +/// {@template app_theme} +/// Composes [ThemeData] with [ColorScheme.fromSeed] and custom +/// [ThemeExtension]s for light and dark variants. +/// {@endtemplate} +class AppTheme { + /// The light [ThemeData]. + static ThemeData get toaster { + const appColors = AppColors( + success: Color(0xFF16A34A), + onSuccess: Color(0xFFFFFFFF), + warning: Color(0xFFCA8A04), + onWarning: Color(0xFFFFFFFF), + info: Color(0xFF2563EB), + onInfo: Color(0xFFFFFFFF), + neutral: Color(0xFF3F3F46), + onNeutral: Color(0xFFFFFFFF), + ); + + return ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFFA78BFA)).copyWith( + primary: const Color(0xFFA78BFA), + secondary: const Color(0xFF71717A), + tertiary: const Color(0xFF34D399), + brightness: Brightness.dark, + ), + extensions: const [appColors, AppSpacing()], + ); + } +} diff --git a/packages/toaster_ui/lib/src/widgets/app_button.dart b/packages/toaster_ui/lib/src/widgets/app_button.dart new file mode 100644 index 0000000..a7f942a --- /dev/null +++ b/packages/toaster_ui/lib/src/widgets/app_button.dart @@ -0,0 +1,92 @@ +import 'package:toaster_ui/toaster_ui.dart'; + +/// Visual variants for [AppButton]. +enum AppButtonVariant { + /// A filled button with the primary color. + primary, + + /// A tonal filled button with a secondary color. + secondary, + + /// An outlined button. + outline, +} + +/// Size variants for [AppButton]. +enum AppButtonSize { + /// A small button. + small, + + /// A medium button. + medium, + + /// A large button. + large, +} + +/// {@template app_button} +/// A styled button that composes Material's [FilledButton] and +/// [OutlinedButton] with app-specific sizing and theming. +/// {@endtemplate} +class AppButton extends StatelessWidget { + /// {@macro app_button} + const AppButton({ + required this.onPressed, + required this.child, + this.variant = AppButtonVariant.primary, + this.size = AppButtonSize.medium, + super.key, + }); + + /// Called when the button is tapped. + final VoidCallback? onPressed; + + /// The button's content, typically a [Text] widget. + final Widget child; + + /// The visual variant of the button. + final AppButtonVariant variant; + + /// The size of the button. + final AppButtonSize size; + + @override + Widget build(BuildContext context) { + final spacing = context.appSpacing; + + final padding = switch (size) { + AppButtonSize.small => EdgeInsets.symmetric( + horizontal: spacing.sm, + vertical: spacing.xxs, + ), + AppButtonSize.medium => EdgeInsets.symmetric( + horizontal: spacing.md, + vertical: spacing.xs, + ), + AppButtonSize.large => EdgeInsets.symmetric( + horizontal: spacing.lg, + vertical: spacing.sm, + ), + }; + + final style = ButtonStyle(padding: WidgetStatePropertyAll(padding)); + + return switch (variant) { + AppButtonVariant.primary => FilledButton( + onPressed: onPressed, + style: style, + child: child, + ), + AppButtonVariant.secondary => FilledButton.tonal( + onPressed: onPressed, + style: style, + child: child, + ), + AppButtonVariant.outline => OutlinedButton( + onPressed: onPressed, + style: style, + child: child, + ), + }; + } +} diff --git a/packages/toaster_ui/lib/toaster_ui.dart b/packages/toaster_ui/lib/toaster_ui.dart new file mode 100644 index 0000000..7fbb7f8 --- /dev/null +++ b/packages/toaster_ui/lib/toaster_ui.dart @@ -0,0 +1,10 @@ +/// A Very Good Project created by Very Good CLI. +library; + +export 'package:flutter/material.dart'; + +export 'src/extensions/build_context_extensions.dart'; +export 'src/theme/app_colors.dart'; +export 'src/theme/app_spacing.dart'; +export 'src/theme/app_theme.dart'; +export 'src/widgets/app_button.dart'; diff --git a/packages/toaster_ui/pubspec.yaml b/packages/toaster_ui/pubspec.yaml new file mode 100644 index 0000000..01065ca --- /dev/null +++ b/packages/toaster_ui/pubspec.yaml @@ -0,0 +1,20 @@ +name: toaster_ui +description: A Very Good Project created by Very Good CLI. +version: 0.1.0+1 +publish_to: none + +environment: + sdk: ^3.11.0 + flutter: ^3.41.0 + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + mocktail: ^1.0.5 + very_good_analysis: ^10.2.0 + +resolution: workspace diff --git a/packages/toaster_ui/test/helpers/helpers.dart b/packages/toaster_ui/test/helpers/helpers.dart new file mode 100644 index 0000000..b15fe65 --- /dev/null +++ b/packages/toaster_ui/test/helpers/helpers.dart @@ -0,0 +1 @@ +export 'pump_app.dart'; diff --git a/packages/toaster_ui/test/helpers/pump_app.dart b/packages/toaster_ui/test/helpers/pump_app.dart new file mode 100644 index 0000000..b8ba4be --- /dev/null +++ b/packages/toaster_ui/test/helpers/pump_app.dart @@ -0,0 +1,16 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:toaster_ui/toaster_ui.dart'; + +/// Extension on [WidgetTester] to pump a widget wrapped in [MaterialApp] +/// with the full app theme. +extension PumpApp on WidgetTester { + /// Pumps [widget] wrapped in a [MaterialApp] with [AppTheme.toaster]. + Future pumpApp(Widget widget, {ThemeData? theme}) { + return pumpWidget( + MaterialApp( + theme: theme ?? AppTheme.toaster, + home: Scaffold(body: widget), + ), + ); + } +} diff --git a/packages/toaster_ui/test/src/extensions/build_context_extensions_test.dart b/packages/toaster_ui/test/src/extensions/build_context_extensions_test.dart new file mode 100644 index 0000000..7d9cfbc --- /dev/null +++ b/packages/toaster_ui/test/src/extensions/build_context_extensions_test.dart @@ -0,0 +1,36 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:toaster_ui/toaster_ui.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + group('AppThemeBuildContext', () { + testWidgets('appColors returns AppColors from theme', (tester) async { + late AppColors colors; + await tester.pumpApp( + Builder( + builder: (context) { + colors = context.appColors; + return const SizedBox(); + }, + ), + ); + + expect(colors, isA()); + }); + + testWidgets('appSpacing returns AppSpacing from theme', (tester) async { + late AppSpacing spacing; + await tester.pumpApp( + Builder( + builder: (context) { + spacing = context.appSpacing; + return const SizedBox(); + }, + ), + ); + + expect(spacing, isA()); + }); + }); +} diff --git a/packages/toaster_ui/test/src/theme/app_colors_test.dart b/packages/toaster_ui/test/src/theme/app_colors_test.dart new file mode 100644 index 0000000..f6770e0 --- /dev/null +++ b/packages/toaster_ui/test/src/theme/app_colors_test.dart @@ -0,0 +1,63 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:toaster_ui/toaster_ui.dart'; + +void main() { + group('AppColors', () { + const colors = AppColors( + success: Color(0xFF16A34A), + onSuccess: Color(0xFFFFFFFF), + warning: Color(0xFFCA8A04), + onWarning: Color(0xFFFFFFFF), + info: Color(0xFF2563EB), + onInfo: Color(0xFFFFFFFF), + neutral: Color(0xFF3F3F46), + onNeutral: Color(0xFFFFFFFF), + ); + + test('copyWith returns a new instance with updated values', () { + final updated = colors.copyWith(success: const Color(0xFF000000)); + expect(updated.success, const Color(0xFF000000)); + expect(updated.onSuccess, colors.onSuccess); + expect(updated.warning, colors.warning); + expect(updated.onWarning, colors.onWarning); + expect(updated.info, colors.info); + expect(updated.onInfo, colors.onInfo); + }); + + test('copyWith returns identical instance when no values are provided', () { + final copy = colors.copyWith(); + expect(copy.success, colors.success); + expect(copy.onSuccess, colors.onSuccess); + expect(copy.warning, colors.warning); + expect(copy.onWarning, colors.onWarning); + expect(copy.info, colors.info); + expect(copy.onInfo, colors.onInfo); + }); + + test('lerp returns this when other is not AppColors', () { + final result = colors.lerp(null, 0.5); + expect(result, colors); + }); + + test('lerp interpolates between two AppColors', () { + const other = AppColors( + success: Color(0xFF000000), + onSuccess: Color(0xFF000000), + warning: Color(0xFF000000), + onWarning: Color(0xFF000000), + info: Color(0xFF000000), + onInfo: Color(0xFF000000), + neutral: Color(0xFF000000), + onNeutral: Color(0xFF000000), + ); + + final result = colors.lerp(other, 0.5); + expect(result.success, isNotNull); + expect(result.onSuccess, isNotNull); + expect(result.warning, isNotNull); + expect(result.onWarning, isNotNull); + expect(result.info, isNotNull); + expect(result.onInfo, isNotNull); + }); + }); +} diff --git a/packages/toaster_ui/test/src/theme/app_spacing_test.dart b/packages/toaster_ui/test/src/theme/app_spacing_test.dart new file mode 100644 index 0000000..d64ad53 --- /dev/null +++ b/packages/toaster_ui/test/src/theme/app_spacing_test.dart @@ -0,0 +1,66 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:toaster_ui/toaster_ui.dart'; + +void main() { + group('AppSpacing', () { + const spacing = AppSpacing(); + + test('has correct default values', () { + expect(spacing.xxs, 4); + expect(spacing.xs, 8); + expect(spacing.sm, 12); + expect(spacing.md, 16); + expect(spacing.lg, 24); + expect(spacing.xlg, 32); + expect(spacing.xxlg, 48); + }); + + test('copyWith returns a new instance with updated values', () { + final updated = spacing.copyWith(xxs: 2, md: 20); + expect(updated.xxs, 2); + expect(updated.xs, spacing.xs); + expect(updated.sm, spacing.sm); + expect(updated.md, 20); + expect(updated.lg, spacing.lg); + expect(updated.xlg, spacing.xlg); + expect(updated.xxlg, spacing.xxlg); + }); + + test('copyWith returns identical instance when no values are provided', () { + final copy = spacing.copyWith(); + expect(copy.xxs, spacing.xxs); + expect(copy.xs, spacing.xs); + expect(copy.sm, spacing.sm); + expect(copy.md, spacing.md); + expect(copy.lg, spacing.lg); + expect(copy.xlg, spacing.xlg); + expect(copy.xxlg, spacing.xxlg); + }); + + test('lerp returns this when other is not AppSpacing', () { + final result = spacing.lerp(null, 0.5); + expect(result, spacing); + }); + + test('lerp interpolates between two AppSpacing instances', () { + const other = AppSpacing( + xxs: 8, + xs: 16, + sm: 24, + md: 32, + lg: 48, + xlg: 64, + xxlg: 96, + ); + + final result = spacing.lerp(other, 0.5); + expect(result.xxs, 6); + expect(result.xs, 12); + expect(result.sm, 18); + expect(result.md, 24); + expect(result.lg, 36); + expect(result.xlg, 48); + expect(result.xxlg, 72); + }); + }); +} diff --git a/packages/toaster_ui/test/src/theme/app_theme_test.dart b/packages/toaster_ui/test/src/theme/app_theme_test.dart new file mode 100644 index 0000000..15649b7 --- /dev/null +++ b/packages/toaster_ui/test/src/theme/app_theme_test.dart @@ -0,0 +1,24 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:toaster_ui/toaster_ui.dart'; + +void main() { + group('AppTheme', () { + group('light', () { + test('returns a ThemeData', () { + expect(AppTheme.toaster, isA()); + }); + + test('has AppColors extension', () { + expect(AppTheme.toaster.extension(), isNotNull); + }); + + test('has AppSpacing extension', () { + expect(AppTheme.toaster.extension(), isNotNull); + }); + + test('has light brightness', () { + expect(AppTheme.toaster.brightness, Brightness.dark); + }); + }); + }); +} diff --git a/packages/toaster_ui/test/src/widgets/app_button_test.dart b/packages/toaster_ui/test/src/widgets/app_button_test.dart new file mode 100644 index 0000000..301199e --- /dev/null +++ b/packages/toaster_ui/test/src/widgets/app_button_test.dart @@ -0,0 +1,89 @@ +// Not required for test files. +// ignore_for_file: prefer_const_constructors + +import 'package:flutter_test/flutter_test.dart'; +import 'package:toaster_ui/toaster_ui.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + group('AppButton', () { + testWidgets('renders child', (tester) async { + await tester.pumpApp(AppButton(onPressed: () {}, child: Text('Tap me'))); + + expect(find.text('Tap me'), findsOneWidget); + }); + + testWidgets('calls onPressed when tapped', (tester) async { + var tapped = false; + await tester.pumpApp( + AppButton(onPressed: () => tapped = true, child: Text('Tap me')), + ); + + await tester.tap(find.byType(AppButton)); + expect(tapped, isTrue); + }); + + testWidgets('does not call onPressed when disabled', (tester) async { + await tester.pumpApp(AppButton(onPressed: null, child: Text('Disabled'))); + + await tester.tap(find.byType(AppButton)); + }); + + testWidgets('renders FilledButton for primary variant', (tester) async { + await tester.pumpApp(AppButton(onPressed: () {}, child: Text('Primary'))); + + expect(find.byType(FilledButton), findsOneWidget); + }); + + testWidgets('renders FilledButton.tonal for secondary variant', ( + tester, + ) async { + await tester.pumpApp( + AppButton( + onPressed: () {}, + variant: AppButtonVariant.secondary, + child: Text('Secondary'), + ), + ); + + expect(find.byType(FilledButton), findsOneWidget); + }); + + testWidgets('renders OutlinedButton for outline variant', (tester) async { + await tester.pumpApp( + AppButton( + onPressed: () {}, + variant: AppButtonVariant.outline, + child: Text('Outline'), + ), + ); + + expect(find.byType(OutlinedButton), findsOneWidget); + }); + + testWidgets('renders with small size', (tester) async { + await tester.pumpApp( + AppButton( + onPressed: () {}, + size: AppButtonSize.small, + child: Text('Small'), + ), + ); + + expect(find.text('Small'), findsOneWidget); + }); + + testWidgets('renders with large size', (tester) async { + await tester.pumpApp( + AppButton( + onPressed: () {}, + size: AppButtonSize.large, + child: Text('Large'), + ), + ); + + expect(find.text('Large'), findsOneWidget); + }); + }); +} diff --git a/packages/toaster_ui/widgetbook/.gitignore b/packages/toaster_ui/widgetbook/.gitignore new file mode 100644 index 0000000..3c5430a --- /dev/null +++ b/packages/toaster_ui/widgetbook/.gitignore @@ -0,0 +1,34 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# VSCode related +.vscode/* + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ +pubspec.lock + +# Test related +coverage diff --git a/packages/toaster_ui/widgetbook/analysis_options.yaml b/packages/toaster_ui/widgetbook/analysis_options.yaml new file mode 100644 index 0000000..cfe6f91 --- /dev/null +++ b/packages/toaster_ui/widgetbook/analysis_options.yaml @@ -0,0 +1,5 @@ +include: package:very_good_analysis/analysis_options.yaml + +analyzer: + exclude: + - "**/*.g.dart" diff --git a/packages/toaster_ui/widgetbook/lib/main.dart b/packages/toaster_ui/widgetbook/lib/main.dart new file mode 100644 index 0000000..ccfce2f --- /dev/null +++ b/packages/toaster_ui/widgetbook/lib/main.dart @@ -0,0 +1,7 @@ +import 'package:flutter/material.dart'; +import 'package:widgetbook_catalog/widgetbook/widgetbook.dart'; + +void main() { + WidgetsFlutterBinding.ensureInitialized(); + runApp(const WidgetbookApp()); +} diff --git a/packages/toaster_ui/widgetbook/lib/widgetbook/use_cases/app_button.dart b/packages/toaster_ui/widgetbook/lib/widgetbook/use_cases/app_button.dart new file mode 100644 index 0000000..562c9a2 --- /dev/null +++ b/packages/toaster_ui/widgetbook/lib/widgetbook/use_cases/app_button.dart @@ -0,0 +1,47 @@ +import 'package:flutter/material.dart'; +import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; +import 'package:toaster_ui/toaster_ui.dart'; + +/// Primary [AppButton] use case. +@widgetbook.UseCase(name: 'primary', type: AppButton) +Widget primary(BuildContext context) => Center( + child: AppButton(onPressed: () {}, child: const Text('Primary')), +); + +/// Secondary [AppButton] use case. +@widgetbook.UseCase(name: 'secondary', type: AppButton) +Widget secondary(BuildContext context) => Center( + child: AppButton( + onPressed: () {}, + variant: AppButtonVariant.secondary, + child: const Text('Secondary'), + ), +); + +/// Outline [AppButton] use case. +@widgetbook.UseCase(name: 'outline', type: AppButton) +Widget outline(BuildContext context) => Center( + child: AppButton( + onPressed: () {}, + variant: AppButtonVariant.outline, + child: const Text('Outline'), + ), +); + +/// Disabled [AppButton] use case. +@widgetbook.UseCase(name: 'disabled', type: AppButton) +Widget disabled(BuildContext context) => + const Center(child: AppButton(onPressed: null, child: Text('Disabled'))); + +/// All sizes [AppButton] use case. +@widgetbook.UseCase(name: 'all sizes', type: AppButton) +Widget allSizes(BuildContext context) => Center( + child: Column( + mainAxisSize: MainAxisSize.min, + spacing: 8, + children: [ + for (final size in AppButtonSize.values) + AppButton(onPressed: () {}, size: size, child: Text(size.name)), + ], + ), +); diff --git a/packages/toaster_ui/widgetbook/lib/widgetbook/widgetbook.dart b/packages/toaster_ui/widgetbook/lib/widgetbook/widgetbook.dart new file mode 100644 index 0000000..7f388a8 --- /dev/null +++ b/packages/toaster_ui/widgetbook/lib/widgetbook/widgetbook.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; +import 'package:widgetbook_catalog/widgetbook/widgetbook.directories.g.dart'; +import 'package:widgetbook_catalog/widgetbook/widgets/widgets.dart'; +import 'package:toaster_ui/toaster_ui.dart'; + +/// The Widgetbook catalog app. +@widgetbook.App() +class WidgetbookApp extends StatelessWidget { + /// Creates a [WidgetbookApp]. + const WidgetbookApp({super.key}); + + @override + Widget build(BuildContext context) { + return Widgetbook.material( + directories: directories, + addons: [ + BuilderAddon( + name: 'Decorator', + builder: (context, child) { + return UseCaseDecorator(child: child); + }, + ), + ThemeAddon( + themes: [ + WidgetbookTheme(name: 'Light', data: AppTheme.light), + WidgetbookTheme(name: 'Dark', data: AppTheme.dark), + ], + themeBuilder: (context, theme, child) { + return Theme( + data: theme, + child: DefaultTextStyle( + style: theme.textTheme.bodyMedium ?? const TextStyle(), + child: child, + ), + ); + }, + ), + ], + ); + } +} diff --git a/packages/toaster_ui/widgetbook/lib/widgetbook/widgetbook.directories.g.dart b/packages/toaster_ui/widgetbook/lib/widgetbook/widgetbook.directories.g.dart new file mode 100644 index 0000000..e6d098e --- /dev/null +++ b/packages/toaster_ui/widgetbook/lib/widgetbook/widgetbook.directories.g.dart @@ -0,0 +1,53 @@ +// dart format width=80 +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_import, prefer_relative_imports, directives_ordering + +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// AppGenerator +// ************************************************************************** + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'package:widgetbook/widgetbook.dart' as _widgetbook; +import 'package:widgetbook_catalog/widgetbook/use_cases/app_button.dart' + as _widgetbook_catalog_widgetbook_use_cases_app_button; + +final directories = <_widgetbook.WidgetbookNode>[ + _widgetbook.WidgetbookFolder( + name: 'widgets', + children: [ + _widgetbook.WidgetbookComponent( + name: 'AppButton', + useCases: [ + _widgetbook.WidgetbookUseCase( + name: 'all sizes', + builder: + _widgetbook_catalog_widgetbook_use_cases_app_button.allSizes, + ), + _widgetbook.WidgetbookUseCase( + name: 'disabled', + builder: + _widgetbook_catalog_widgetbook_use_cases_app_button.disabled, + ), + _widgetbook.WidgetbookUseCase( + name: 'outline', + builder: + _widgetbook_catalog_widgetbook_use_cases_app_button.outline, + ), + _widgetbook.WidgetbookUseCase( + name: 'primary', + builder: + _widgetbook_catalog_widgetbook_use_cases_app_button.primary, + ), + _widgetbook.WidgetbookUseCase( + name: 'secondary', + builder: + _widgetbook_catalog_widgetbook_use_cases_app_button.secondary, + ), + ], + ), + ], + ), +]; diff --git a/packages/toaster_ui/widgetbook/lib/widgetbook/widgets/use_case_decorator.dart b/packages/toaster_ui/widgetbook/lib/widgetbook/widgets/use_case_decorator.dart new file mode 100644 index 0000000..f854aca --- /dev/null +++ b/packages/toaster_ui/widgetbook/lib/widgetbook/widgets/use_case_decorator.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; + +/// A decorator that wraps every use case with a consistent background. +class UseCaseDecorator extends StatelessWidget { + /// Creates a [UseCaseDecorator]. + const UseCaseDecorator({required this.child, super.key}); + + /// The use case widget to wrap. + final Widget child; + + @override + Widget build(BuildContext context) { + final colorScheme = Theme.of(context).colorScheme; + return ColoredBox( + color: colorScheme.surfaceContainerHighest, + child: SizedBox.expand(child: Material(child: child)), + ); + } +} diff --git a/packages/toaster_ui/widgetbook/lib/widgetbook/widgets/widgets.dart b/packages/toaster_ui/widgetbook/lib/widgetbook/widgets/widgets.dart new file mode 100644 index 0000000..a4827d8 --- /dev/null +++ b/packages/toaster_ui/widgetbook/lib/widgetbook/widgets/widgets.dart @@ -0,0 +1 @@ +export 'use_case_decorator.dart'; diff --git a/packages/toaster_ui/widgetbook/pubspec.yaml b/packages/toaster_ui/widgetbook/pubspec.yaml new file mode 100644 index 0000000..aafec53 --- /dev/null +++ b/packages/toaster_ui/widgetbook/pubspec.yaml @@ -0,0 +1,26 @@ +name: widgetbook_catalog +description: "Widgetbook catalog for Toaster Ui" +publish_to: none +version: 1.0.0+1 + +environment: + sdk: ^3.11.0 + flutter: ^3.41.0 + +dependencies: + flutter: + sdk: flutter + toaster_ui: + path: .. + widgetbook: ^3.22.0 + widgetbook_annotation: ^3.11.0 + +dev_dependencies: + build_runner: ^2.13.1 + flutter_test: + sdk: flutter + very_good_analysis: ^10.2.0 + widgetbook_generator: ^3.22.0 + +flutter: + uses-material-design: true diff --git a/plugins/toaster_utils/.github/ISSUE_TEMPLATE/bug_report.md b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..50a4c7b --- /dev/null +++ b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,29 @@ +--- +name: Bug Report +about: Create a report to help us improve +title: "fix: " +labels: bug +--- + +**Description** + +A clear and concise description of what the bug is. + +**Steps To Reproduce** + +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected Behavior** + +A clear and concise description of what you expected to happen. + +**Screenshots** + +If applicable, add screenshots to help explain your problem. + +**Additional Context** + +Add any other context about the problem here. diff --git a/plugins/toaster_utils/.github/ISSUE_TEMPLATE/build.md b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/build.md new file mode 100644 index 0000000..0cf8e62 --- /dev/null +++ b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/build.md @@ -0,0 +1,14 @@ +--- +name: Build System +about: Changes that affect the build system or external dependencies +title: "build: " +labels: build +--- + +**Description** + +Describe what changes need to be done to the build system and why. + +**Requirements** + +- [ ] The build system is passing diff --git a/plugins/toaster_utils/.github/ISSUE_TEMPLATE/chore.md b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/chore.md new file mode 100644 index 0000000..498ebfd --- /dev/null +++ b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/chore.md @@ -0,0 +1,14 @@ +--- +name: Chore +about: Other changes that don't modify src or test files +title: "chore: " +labels: chore +--- + +**Description** + +Clearly describe what change is needed and why. If this changes code then please use another issue type. + +**Requirements** + +- [ ] No functional changes to the code diff --git a/plugins/toaster_utils/.github/ISSUE_TEMPLATE/ci.md b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/ci.md new file mode 100644 index 0000000..fa2dd9e --- /dev/null +++ b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/ci.md @@ -0,0 +1,14 @@ +--- +name: Continuous Integration +about: Changes to the CI configuration files and scripts +title: "ci: " +labels: ci +--- + +**Description** + +Describe what changes need to be done to the ci/cd system and why. + +**Requirements** + +- [ ] The ci system is passing diff --git a/plugins/toaster_utils/.github/ISSUE_TEMPLATE/config.yml b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..ec4bb38 --- /dev/null +++ b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false \ No newline at end of file diff --git a/plugins/toaster_utils/.github/ISSUE_TEMPLATE/documentation.md b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/documentation.md new file mode 100644 index 0000000..f494a4d --- /dev/null +++ b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/documentation.md @@ -0,0 +1,14 @@ +--- +name: Documentation +about: Improve the documentation so all collaborators have a common understanding +title: "docs: " +labels: documentation +--- + +**Description** + +Clearly describe what documentation you are looking to add or improve. + +**Requirements** + +- [ ] Requirements go here diff --git a/plugins/toaster_utils/.github/ISSUE_TEMPLATE/feature_request.md b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..ddd2fcc --- /dev/null +++ b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,18 @@ +--- +name: Feature Request +about: A new feature to be added to the project +title: "feat: " +labels: feature +--- + +**Description** + +Clearly describe what you are looking to add. The more context the better. + +**Requirements** + +- [ ] Checklist of requirements to be fulfilled + +**Additional Context** + +Add any other context or screenshots about the feature request go here. diff --git a/plugins/toaster_utils/.github/ISSUE_TEMPLATE/performance.md b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/performance.md new file mode 100644 index 0000000..699b8d4 --- /dev/null +++ b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/performance.md @@ -0,0 +1,14 @@ +--- +name: Performance Update +about: A code change that improves performance +title: "perf: " +labels: performance +--- + +**Description** + +Clearly describe what code needs to be changed and what the performance impact is going to be. Bonus point's if you can tie this directly to user experience. + +**Requirements** + +- [ ] There is no drop in test coverage. diff --git a/plugins/toaster_utils/.github/ISSUE_TEMPLATE/refactor.md b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/refactor.md new file mode 100644 index 0000000..1626c57 --- /dev/null +++ b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/refactor.md @@ -0,0 +1,14 @@ +--- +name: Refactor +about: A code change that neither fixes a bug nor adds a feature +title: "refactor: " +labels: refactor +--- + +**Description** + +Clearly describe what needs to be refactored and why. Please provide links to related issues (bugs or upcoming features) in order to help prioritize. + +**Requirements** + +- [ ] There is no drop in test coverage. diff --git a/plugins/toaster_utils/.github/ISSUE_TEMPLATE/revert.md b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/revert.md new file mode 100644 index 0000000..9d121dc --- /dev/null +++ b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/revert.md @@ -0,0 +1,16 @@ +--- +name: Revert Commit +about: Reverts a previous commit +title: "revert: " +labels: revert +--- + +**Description** + +Provide a link to a PR/Commit that you are looking to revert and why. + +**Requirements** + +- [ ] Change has been reverted +- [ ] No change in test coverage has happened +- [ ] A new ticket is created for any follow on work that needs to happen diff --git a/plugins/toaster_utils/.github/ISSUE_TEMPLATE/style.md b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/style.md new file mode 100644 index 0000000..02244a7 --- /dev/null +++ b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/style.md @@ -0,0 +1,14 @@ +--- +name: Style Changes +about: Changes that do not affect the meaning of the code (white space, formatting, missing semi-colons, etc) +title: "style: " +labels: style +--- + +**Description** + +Clearly describe what you are looking to change and why. + +**Requirements** + +- [ ] There is no drop in test coverage. diff --git a/plugins/toaster_utils/.github/ISSUE_TEMPLATE/test.md b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/test.md new file mode 100644 index 0000000..431a7ea --- /dev/null +++ b/plugins/toaster_utils/.github/ISSUE_TEMPLATE/test.md @@ -0,0 +1,14 @@ +--- +name: Test +about: Adding missing tests or correcting existing tests +title: "test: " +labels: test +--- + +**Description** + +List out the tests that need to be added or changed. Please also include any information as to why this was not covered in the past. + +**Requirements** + +- [ ] There is no drop in test coverage. diff --git a/plugins/toaster_utils/.github/PULL_REQUEST_TEMPLATE.md b/plugins/toaster_utils/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..8ff7bf6 --- /dev/null +++ b/plugins/toaster_utils/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,24 @@ + + +## Description + + + +## Type of Change + + + +- [ ] ✨ New feature (non-breaking change which adds functionality) +- [ ] 🛠️ Bug fix (non-breaking change which fixes an issue) +- [ ] ❌ Breaking change (fix or feature that would cause existing functionality to change) +- [ ] 🧹 Code refactor +- [ ] ✅ Build configuration change +- [ ] 📝 Documentation +- [ ] 🗑️ Chore +- [ ] 🧪 Test diff --git a/plugins/toaster_utils/.github/cspell.json b/plugins/toaster_utils/.github/cspell.json new file mode 100644 index 0000000..bdf826f --- /dev/null +++ b/plugins/toaster_utils/.github/cspell.json @@ -0,0 +1,21 @@ +{ + "version": "0.2", + "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json", + "dictionaries": ["vgv_allowed", "vgv_forbidden"], + "dictionaryDefinitions": [ + { + "name": "vgv_allowed", + "path": "https://raw.githubusercontent.com/verygoodopensource/very_good_dictionaries/main/allowed.txt", + "description": "Allowed VGV Spellings" + }, + { + "name": "vgv_forbidden", + "path": "https://raw.githubusercontent.com/verygoodopensource/very_good_dictionaries/main/forbidden.txt", + "description": "Forbidden VGV Spellings" + } + ], + "useGitignore": true, + "words": [ + "fluttium" + ] +} diff --git a/plugins/toaster_utils/.github/dependabot.yaml b/plugins/toaster_utils/.github/dependabot.yaml new file mode 100644 index 0000000..9f27e44 --- /dev/null +++ b/plugins/toaster_utils/.github/dependabot.yaml @@ -0,0 +1,31 @@ +version: 2 +enable-beta-ecosystems: true +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + - package-ecosystem: "pub" + directory: "/toaster_utils" + schedule: + interval: "daily" + - package-ecosystem: "pub" + directory: "/toaster_utils/example" + schedule: + interval: "daily" + - package-ecosystem: "pub" + directory: "/toaster_utils_platform_interface" + schedule: + interval: "daily" + - package-ecosystem: "pub" + directory: "/toaster_utils_android" + schedule: + interval: "daily" + - package-ecosystem: "pub" + directory: "/toaster_utils_ios" + schedule: + interval: "daily" + - package-ecosystem: "pub" + directory: "/toaster_utils_macos" + schedule: + interval: "daily" \ No newline at end of file diff --git a/plugins/toaster_utils/.github/workflows/ci.yaml b/plugins/toaster_utils/.github/workflows/ci.yaml new file mode 100644 index 0000000..112f425 --- /dev/null +++ b/plugins/toaster_utils/.github/workflows/ci.yaml @@ -0,0 +1,10 @@ +name: ci + +on: + pull_request: + branches: + - main + +jobs: + build: + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/semantic_pull_request.yml@v1 diff --git a/plugins/toaster_utils/.github/workflows/license_check.yaml b/plugins/toaster_utils/.github/workflows/license_check.yaml new file mode 100644 index 0000000..e33c671 --- /dev/null +++ b/plugins/toaster_utils/.github/workflows/license_check.yaml @@ -0,0 +1,34 @@ +name: license_check + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + branches: + - main + paths: + - "toaster_utils/pubspec.yaml" + - "toaster_utils_platform_interface/pubspec.yaml" + - ".github/workflows/license_check.yaml" + push: + branches: + - main + paths: + - "toaster_utils/pubspec.yaml" + - "toaster_utils_platform_interface/pubspec.yaml" + - ".github/workflows/license_check.yaml" + +jobs: + license_check: + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/license_check.yml@v1 + with: + allowed: "MIT,BSD-3-Clause,BSD-2-Clause,Apache-2.0" + working_directory: toaster_utils + + license_check_platform_interface: + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/license_check.yml@v1 + with: + allowed: "MIT,BSD-3-Clause,BSD-2-Clause,Apache-2.0" + working_directory: toaster_utils_platform_interface diff --git a/plugins/toaster_utils/.github/workflows/toaster_utils.yaml b/plugins/toaster_utils/.github/workflows/toaster_utils.yaml new file mode 100644 index 0000000..dbec00e --- /dev/null +++ b/plugins/toaster_utils/.github/workflows/toaster_utils.yaml @@ -0,0 +1,181 @@ +name: toaster_utils + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + paths: + - ".github/workflows/toaster_utils.yaml" + - "toaster_utils/**" + push: + branches: + - main + paths: + - ".github/workflows/toaster_utils.yaml" + - "toaster_utils/**" + +jobs: + spell-check: + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/spell_check.yml@v1 + with: + includes: | + **/*.md + !brick/**/*.md + .*/**/*.md + modified_files_only: false + + build: + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1 + with: + flutter_version: 3.41.1 + working_directory: toaster_utils + + + android: + runs-on: macos-latest + + defaults: + run: + working-directory: toaster_utils/example + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v3 + with: + distribution: "temurin" + java-version: "11" + + - uses: subosito/flutter-action@v2 + + - name: Install Fluttium + run: flutter pub global activate fluttium_cli + + - name: AVD Cache + uses: actions/cache@v3 + id: avd-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: avd-29 + + - name: Cache AVD Snapshot + if: steps.avd-cache.outputs.cache-hit != 'true' + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 29 + force-avd-creation: false + emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: false + script: echo "Generated AVD snapshot for caching." + + - name: E2E Tests + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 29 + script: fluttium test flows/test_platform_name.yaml -d android + working-directory: toaster_utils/example + + ios: + runs-on: macos-latest + + defaults: + run: + working-directory: toaster_utils/example + + steps: + - uses: actions/checkout@v4 + + - uses: subosito/flutter-action@v2 + + - name: Install Fluttium + run: flutter pub global activate fluttium_cli + + - name: Start Simulator + # Start an iPhone simulator + run: | + UDID=$(xcrun xctrace list devices | grep "^iPhone" | awk '{gsub(/[()]/,""); print $NF}' | head -n 1) + echo $UDID + xcrun simctl boot "${UDID:?No Simulator with this name found}" + + - name: E2E Tests + run: fluttium test flows/test_platform_name.yaml -d iPhone + + linux: + runs-on: ubuntu-latest + if: false # todo(renancaraujo): https://github.com/wolfenrain/fluttium/issues/345 + defaults: + run: + working-directory: toaster_utils/example + + steps: + - uses: actions/checkout@v4 + + - uses: subosito/flutter-action@v2 + + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install -y libgtk-3-dev libx11-dev pkg-config cmake ninja-build libblkid-dev liblzma-dev + + - name: Install Fluttium + run: flutter pub global activate fluttium_cli + + - name: E2E Tests + run: xvfb-run fluttium test flows/test_platform_name.yaml -d linux + + macos: + runs-on: macos-13 + + defaults: + run: + working-directory: toaster_utils/example + + steps: + - uses: actions/checkout@v4 + + - uses: subosito/flutter-action@v2 + + - name: Install Fluttium + run: flutter pub global activate fluttium_cli + + - name: E2E Tests + run: fluttium test flows/test_platform_name.yaml -d macos + + web: + runs-on: ubuntu-latest + + defaults: + run: + working-directory: toaster_utils/example + + steps: + - uses: actions/checkout@v4 + + - uses: subosito/flutter-action@v2 + + - name: Install Fluttium + run: flutter pub global activate fluttium_cli + + - name: E2E Tests + run: xvfb-run fluttium test flows/test_platform_name.yaml -d chrome + + windows: + runs-on: windows-2019 + + defaults: + run: + working-directory: toaster_utils/example + + steps: + - uses: actions/checkout@v4 + + - uses: subosito/flutter-action@v2 + + - name: Install Fluttium + run: flutter pub global activate fluttium_cli + + - name: E2E Tests + run: fluttium test flows/test_platform_name.yaml -d windows diff --git a/plugins/toaster_utils/.github/workflows/toaster_utils_android.yaml b/plugins/toaster_utils/.github/workflows/toaster_utils_android.yaml new file mode 100644 index 0000000..a189717 --- /dev/null +++ b/plugins/toaster_utils/.github/workflows/toaster_utils_android.yaml @@ -0,0 +1,25 @@ +name: toaster_utils_android + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + paths: + - ".github/workflows/toaster_utils_android.yaml" + - "toaster_utils_android/**" + push: + branches: + - main + paths: + - ".github/workflows/toaster_utils_android.yaml" + - "toaster_utils_android/**" + +jobs: + build: + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1 + with: + flutter_version: 3.41.1 + working_directory: toaster_utils_android + diff --git a/plugins/toaster_utils/.github/workflows/toaster_utils_ios.yaml b/plugins/toaster_utils/.github/workflows/toaster_utils_ios.yaml new file mode 100644 index 0000000..3c60e04 --- /dev/null +++ b/plugins/toaster_utils/.github/workflows/toaster_utils_ios.yaml @@ -0,0 +1,25 @@ +name: toaster_utils_ios + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + paths: + - ".github/workflows/toaster_utils_ios.yaml" + - "toaster_utils_ios/**" + push: + branches: + - main + paths: + - ".github/workflows/toaster_utils_ios.yaml" + - "toaster_utils_ios/**" + +jobs: + build: + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1 + with: + flutter_version: 3.41.1 + working_directory: toaster_utils_ios + diff --git a/plugins/toaster_utils/.github/workflows/toaster_utils_macos.yaml b/plugins/toaster_utils/.github/workflows/toaster_utils_macos.yaml new file mode 100644 index 0000000..221b335 --- /dev/null +++ b/plugins/toaster_utils/.github/workflows/toaster_utils_macos.yaml @@ -0,0 +1,25 @@ +name: toaster_utils_macos + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + paths: + - ".github/workflows/toaster_utils_macos.yaml" + - "toaster_utils_macos/**" + push: + branches: + - main + paths: + - ".github/workflows/toaster_utils_macos.yaml" + - "toaster_utils_macos/**" + +jobs: + build: + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1 + with: + flutter_version: 3.41.1 + working_directory: toaster_utils_macos + diff --git a/plugins/toaster_utils/.github/workflows/toaster_utils_platform_interface.yaml b/plugins/toaster_utils/.github/workflows/toaster_utils_platform_interface.yaml new file mode 100644 index 0000000..3687c11 --- /dev/null +++ b/plugins/toaster_utils/.github/workflows/toaster_utils_platform_interface.yaml @@ -0,0 +1,25 @@ +name: toaster_utils_platform_interface + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + paths: + - ".github/workflows/toaster_utils_platform_interface.yaml" + - "toaster_utils_platform_interface/**" + push: + branches: + - main + paths: + - ".github/workflows/toaster_utils_platform_interface.yaml" + - "toaster_utils_platform_interface/**" + +jobs: + build: + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1 + with: + flutter_version: 3.41.1 + working_directory: toaster_utils_platform_interface + diff --git a/plugins/toaster_utils/.gitignore b/plugins/toaster_utils/.gitignore new file mode 100644 index 0000000..4aa0df8 --- /dev/null +++ b/plugins/toaster_utils/.gitignore @@ -0,0 +1,48 @@ +.DS_Store +.atom/ +.idea/ +.vscode/ + +.packages +.pub/ +.dart_tool/ +pubspec.lock +flutter_export_environment.sh +coverage/ + +Podfile.lock +Pods/ +.symlinks/ +**/Flutter/App.framework/ +**/Flutter/ephemeral/ +**/Flutter/Flutter.podspec +**/Flutter/Flutter.framework/ +**/Flutter/Generated.xcconfig +**/Flutter/flutter_assets/ + +ServiceDefinitions.json +xcuserdata/ +**/DerivedData/ + +local.properties +keystore.properties +.gradle/ +gradlew +gradlew.bat +gradle-wrapper.jar +.flutter-plugins-dependencies +*.iml + +generated_plugin_registrant.cc +generated_plugin_registrant.h +generated_plugin_registrant.dart +GeneratedPluginRegistrant.java +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m +GeneratedPluginRegistrant.swift +build/ +.flutter-plugins + +.project +.classpath +.settings \ No newline at end of file diff --git a/plugins/toaster_utils/LICENSE b/plugins/toaster_utils/LICENSE new file mode 100644 index 0000000..976db89 --- /dev/null +++ b/plugins/toaster_utils/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 org.mars3142 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/plugins/toaster_utils/README.md b/plugins/toaster_utils/README.md new file mode 100644 index 0000000..4c83e21 --- /dev/null +++ b/plugins/toaster_utils/README.md @@ -0,0 +1,42 @@ +# toaster_utils + +[![Very Good Ventures][logo_white]][very_good_ventures_link_dark] +[![Very Good Ventures][logo_black]][very_good_ventures_link_light] + +Developed with 💙 by [Very Good Ventures][very_good_ventures_link] 🦄 + +![coverage][coverage_badge] +[![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] +[![License: MIT][license_badge]][license_link] + +A Very Good Flutter Federated Plugin created by the [Very Good Ventures Team][very_good_ventures_link]. + +Generated by the [Very Good CLI][very_good_cli_link]. 🤖 + +## Integration tests 🧪 + +Very Good Flutter Plugin uses [fluttium][fluttium_link] for integration tests. Those tests are located +in the front facing package `toaster_utils` example. + +**❗ In order to run the integration tests, you need to have the `fluttium_cli` installed. [See how][fluttium_install].** + +To run the integration tests, run the following command from the root of the project: + +```sh +cd toaster_utils/example +fluttium test flows/test_platform_name.yaml +``` + +[coverage_badge]: toaster_utils/coverage_badge.svg +[license_badge]: https://img.shields.io/badge/license-MIT-blue.svg +[license_link]: https://opensource.org/licenses/MIT +[logo_black]: https://raw.githubusercontent.com/VGVentures/very_good_brand/main/styles/README/vgv_logo_black.png#gh-light-mode-only +[logo_white]: https://raw.githubusercontent.com/VGVentures/very_good_brand/main/styles/README/vgv_logo_white.png#gh-dark-mode-only +[very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg +[very_good_analysis_link]: https://pub.dev/packages/very_good_analysis +[very_good_cli_link]: https://github.com/VeryGoodOpenSource/very_good_cli +[very_good_ventures_link]: https://verygood.ventures/?utm_source=github&utm_medium=banner&utm_campaign=core +[very_good_ventures_link_dark]: https://verygood.ventures/?utm_source=github&utm_medium=banner&utm_campaign=core#gh-dark-mode-only +[very_good_ventures_link_light]: https://verygood.ventures/?utm_source=github&utm_medium=banner&utm_campaign=core#gh-light-mode-only +[fluttium_link]: https://fluttium.dev/ +[fluttium_install]: https://fluttium.dev/docs/getting-started/installing-cli diff --git a/plugins/toaster_utils/toaster_utils/README.md b/plugins/toaster_utils/toaster_utils/README.md new file mode 100644 index 0000000..cd47a42 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/README.md @@ -0,0 +1,26 @@ +# toaster_utils + +[![Very Good Ventures][logo_white]][very_good_ventures_link_dark] +[![Very Good Ventures][logo_black]][very_good_ventures_link_light] + +Developed with 💙 by [Very Good Ventures][very_good_ventures_link] 🦄 + +![coverage][coverage_badge] +[![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] +[![License: MIT][license_badge]][license_link] + +A Very Good Flutter Federated Plugin created by the [Very Good Ventures Team][very_good_ventures_link]. + +Generated by the [Very Good CLI][very_good_cli_link] 🤖 + +[coverage_badge]: coverage_badge.svg +[license_badge]: https://img.shields.io/badge/license-MIT-blue.svg +[license_link]: https://opensource.org/licenses/MIT +[logo_black]: https://raw.githubusercontent.com/VGVentures/very_good_brand/main/styles/README/vgv_logo_black.png#gh-light-mode-only +[logo_white]: https://raw.githubusercontent.com/VGVentures/very_good_brand/main/styles/README/vgv_logo_white.png#gh-dark-mode-only +[very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg +[very_good_analysis_link]: https://pub.dev/packages/very_good_analysis +[very_good_cli_link]: https://github.com/VeryGoodOpenSource/very_good_cli +[very_good_ventures_link]: https://verygood.ventures/?utm_source=github&utm_medium=banner&utm_campaign=core +[very_good_ventures_link_dark]: https://verygood.ventures/?utm_source=github&utm_medium=banner&utm_campaign=core#gh-dark-mode-only +[very_good_ventures_link_light]: https://verygood.ventures/?utm_source=github&utm_medium=banner&utm_campaign=core#gh-light-mode-only diff --git a/plugins/toaster_utils/toaster_utils/analysis_options.yaml b/plugins/toaster_utils/toaster_utils/analysis_options.yaml new file mode 100644 index 0000000..9df80aa --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/analysis_options.yaml @@ -0,0 +1 @@ +include: package:very_good_analysis/analysis_options.yaml diff --git a/plugins/toaster_utils/toaster_utils/coverage_badge.svg b/plugins/toaster_utils/toaster_utils/coverage_badge.svg new file mode 100644 index 0000000..499e98c --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/coverage_badge.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + coverage + coverage + 100% + 100% + + diff --git a/plugins/toaster_utils/toaster_utils/example/.gitignore b/plugins/toaster_utils/toaster_utils/example/.gitignore new file mode 100644 index 0000000..8c5866d --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/.gitignore @@ -0,0 +1,49 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release + +# Fluttium related files +.fluttium_*_launcher.dart \ No newline at end of file diff --git a/plugins/toaster_utils/toaster_utils/example/.metadata b/plugins/toaster_utils/toaster_utils/example/.metadata new file mode 100644 index 0000000..19d7837 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/.metadata @@ -0,0 +1,45 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + channel: stable + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + base_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + - platform: android + create_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + base_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + - platform: ios + create_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + base_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + - platform: linux + create_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + base_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + - platform: macos + create_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + base_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + - platform: web + create_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + base_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + - platform: windows + create_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + base_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/plugins/toaster_utils/toaster_utils/example/README.md b/plugins/toaster_utils/toaster_utils/example/README.md new file mode 100644 index 0000000..3cb2efd --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/README.md @@ -0,0 +1,3 @@ +# toaster_utils_example + +Demonstrates how to use the toaster_utils plugin. diff --git a/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/analysis_options.yaml b/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/analysis_options.yaml new file mode 100644 index 0000000..9df80aa --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/analysis_options.yaml @@ -0,0 +1 @@ +include: package:very_good_analysis/analysis_options.yaml diff --git a/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/lib/check_platform_name.dart b/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/lib/check_platform_name.dart new file mode 100644 index 0000000..d939ac3 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/lib/check_platform_name.dart @@ -0,0 +1,9 @@ +import 'package:check_platform_name/check_platform_name.dart'; +import 'package:fluttium/fluttium.dart'; + +export 'src/check_platform_name.dart'; + +/// Will be executed by Fluttium on startup. +void register(Registry registry) { + registry.registerAction('checkPlatformName', CheckPlatformName.new); +} diff --git a/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/lib/src/check_platform_name.dart b/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/lib/src/check_platform_name.dart new file mode 100644 index 0000000..9461263 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/lib/src/check_platform_name.dart @@ -0,0 +1,70 @@ +import 'dart:io' show Platform; + +import 'package:flutter/foundation.dart'; +import 'package:fluttium/fluttium.dart'; + +/// {@template check_platform_name} +/// An action that checks the expected platform name. +/// +/// Usage: +/// +/// ```yaml +/// - checkPlatformName: +/// ``` +/// {@endtemplate} +class CheckPlatformName extends Action { + /// {@macro check_platform_name} + const CheckPlatformName({ + @visibleForTesting bool Function() isAndroid = _platformIsAndroid, + @visibleForTesting bool Function() isIOS = _platformIsIOS, + @visibleForTesting bool Function() isLinux = _platformIsLinux, + @visibleForTesting bool Function() isMacOS = _platformIsMacOS, + @visibleForTesting bool Function() isWindows = _platformIsWindows, + @visibleForTesting bool isWeb = kIsWeb, + }) : _isAndroid = isAndroid, + _isIOS = isIOS, + _isLinux = isLinux, + _isMacOS = isMacOS, + _isWindows = isWindows, + _isWeb = isWeb; + + final bool _isWeb; + + final bool Function() _isAndroid; + + final bool Function() _isIOS; + + final bool Function() _isLinux; + + final bool Function() _isMacOS; + + final bool Function() _isWindows; + + String get _expectedPlatformName { + if (_isWeb) return 'Web'; + if (_isAndroid()) return 'Android'; + if (_isIOS()) return 'iOS'; + if (_isLinux()) return 'Linux'; + if (_isMacOS()) return 'MacOS'; + if (_isWindows()) return 'Windows'; + throw UnsupportedError('Unsupported platform ${Platform.operatingSystem}'); + } + + @override + Future execute(Tester tester) async { + return ExpectVisible( + text: 'Platform Name: $_expectedPlatformName', + ).execute(tester); + } + + @override + String description() => 'Check platform name: "$_expectedPlatformName"'; +} + +// coverage:ignore-start these are just wrappers for overloading +bool _platformIsAndroid() => Platform.isAndroid; +bool _platformIsIOS() => Platform.isIOS; +bool _platformIsLinux() => Platform.isLinux; +bool _platformIsMacOS() => Platform.isMacOS; +bool _platformIsWindows() => Platform.isWindows; +// coverage:ignore-end diff --git a/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/pubspec.yaml b/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/pubspec.yaml new file mode 100644 index 0000000..f71c383 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/pubspec.yaml @@ -0,0 +1,17 @@ +name: check_platform_name +description: A custom action for Fluttium. +version: 0.1.0+1 + +environment: + sdk: ^3.11.0 + +dependencies: + flutter: + sdk: flutter + fluttium: ^0.1.0 + +dev_dependencies: + flutter_test: + sdk: flutter + mocktail: ^1.0.5 + very_good_analysis: ^10.2.0 diff --git a/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/test/register_test.dart b/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/test/register_test.dart new file mode 100644 index 0000000..5fa4d8d --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/test/register_test.dart @@ -0,0 +1,29 @@ +import 'package:check_platform_name/check_platform_name.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:fluttium/fluttium.dart'; +import 'package:mocktail/mocktail.dart'; + +class _MockRegister extends Mock implements Registry {} + +void main() { + test('can be registered', () { + final registry = _MockRegister(); + when( + () => registry.registerAction( + any(), + any(), + shortHandIs: any(named: 'shortHandIs'), + ), + ).thenAnswer((_) {}); + + register(registry); + + verify( + () => registry.registerAction( + any(that: equals('checkPlatformName')), + any(that: equals(CheckPlatformName.new)), + shortHandIs: any(named: 'shortHandIs', that: isNull), + ), + ).called(1); + }); +} diff --git a/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/test/src/check_platform_name_test.dart b/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/test/src/check_platform_name_test.dart new file mode 100644 index 0000000..fad6508 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/actions/check_platform_name/test/src/check_platform_name_test.dart @@ -0,0 +1,136 @@ +import 'package:check_platform_name/check_platform_name.dart'; +import 'package:flutter/semantics.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:fluttium/fluttium.dart'; +import 'package:mocktail/mocktail.dart'; + +class _MockTester extends Mock implements Tester {} + +class _MockSemanticsNode extends Mock implements SemanticsNode { + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return super.toString(); + } +} + +void main() { + group(CheckPlatformName, () { + late Tester tester; + late SemanticsNode node; + + setUp(() { + tester = _MockTester(); + node = _MockSemanticsNode(); + + when(() => tester.find(any())).thenAnswer((_) async => node); + }); + + test('executes returns true if node was found', () async { + const action = CheckPlatformName(); + + expect(await action.execute(tester), isTrue); + }); + + test('executes returns false if node was not found', () async { + when(() => tester.find(any())).thenAnswer((_) async => null); + + const action = CheckPlatformName(); + + expect(await action.execute(tester), isFalse); + }); + + test('show correct description for every platform', () { + bool isTrue() => true; + bool isFalse() => false; + + final testCases = [ + ( + 'Android', + CheckPlatformName( + isAndroid: isTrue, + isIOS: isFalse, + isWeb: isFalse(), + isWindows: isFalse, + isLinux: isFalse, + isMacOS: isFalse, + ), + ), + ( + 'iOS', + CheckPlatformName( + isAndroid: isFalse, + isIOS: isTrue, + isWeb: isFalse(), + isWindows: isFalse, + isLinux: isFalse, + isMacOS: isFalse, + ), + ), + ( + 'Web', + CheckPlatformName( + isAndroid: isFalse, + isIOS: isFalse, + isWeb: isTrue(), + isWindows: isFalse, + isLinux: isFalse, + isMacOS: isFalse, + ), + ), + ( + 'Linux', + CheckPlatformName( + isAndroid: isFalse, + isIOS: isFalse, + isWeb: isFalse(), + isWindows: isFalse, + isLinux: isTrue, + isMacOS: isFalse, + ), + ), + ( + 'MacOS', + CheckPlatformName( + isAndroid: isFalse, + isIOS: isFalse, + isWeb: isFalse(), + isWindows: isFalse, + isLinux: isFalse, + isMacOS: isTrue, + ), + ), + ( + 'Windows', + CheckPlatformName( + isAndroid: isFalse, + isIOS: isFalse, + isWeb: isFalse(), + isWindows: isTrue, + isLinux: isFalse, + isMacOS: isFalse, + ), + ), + ]; + + for (final testCase in testCases) { + expect( + testCase.$2.description(), + equals('Check platform name: "${testCase.$1}"'), + ); + } + }); + + test('throws UnsupportedError on unknown platform', () { + final action = CheckPlatformName( + isAndroid: () => false, + isIOS: () => false, + isWeb: false, + isWindows: () => false, + isLinux: () => false, + isMacOS: () => false, + ); + + expect(action.description, throwsUnsupportedError); + }); + }); +} diff --git a/plugins/toaster_utils/toaster_utils/example/analysis_options.yaml b/plugins/toaster_utils/toaster_utils/example/analysis_options.yaml new file mode 100644 index 0000000..ce42cd4 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:very_good_analysis/analysis_options.yaml +linter: + rules: + public_member_api_docs: false diff --git a/plugins/toaster_utils/toaster_utils/example/android/.gitignore b/plugins/toaster_utils/toaster_utils/example/android/.gitignore new file mode 100644 index 0000000..6f56801 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/android/.gitignore @@ -0,0 +1,13 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties +**/*.keystore +**/*.jks diff --git a/plugins/toaster_utils/toaster_utils/example/android/app/build.gradle.kts b/plugins/toaster_utils/toaster_utils/example/android/app/build.gradle.kts new file mode 100644 index 0000000..041a2ad --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/android/app/build.gradle.kts @@ -0,0 +1,44 @@ +import java.util.Properties +import java.io.FileInputStream + +plugins { + id("com.android.application") + id("kotlin-android") + id("dev.flutter.flutter-gradle-plugin") +} + +android { + namespace = "org.mars3142.example" + compileSdk = flutter.compileSdkVersion + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_11.toString() + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId = "org.mars3142.example" + minSdk = flutter.minSdkVersion + 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/plugins/toaster_utils/toaster_utils/example/android/app/src/debug/AndroidManifest.xml b/plugins/toaster_utils/toaster_utils/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..f880684 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + + diff --git a/plugins/toaster_utils/toaster_utils/example/android/app/src/main/AndroidManifest.xml b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..19b862e --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/plugins/toaster_utils/toaster_utils/example/android/app/src/main/kotlin/com/example/toaster_utils/example/MainActivity.kt b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/kotlin/com/example/toaster_utils/example/MainActivity.kt new file mode 100644 index 0000000..935410d --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/kotlin/com/example/toaster_utils/example/MainActivity.kt @@ -0,0 +1,6 @@ +package org.mars3142.example + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/drawable-v21/launch_background.xml b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/drawable/launch_background.xml b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/values-night/styles.xml b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..3db14bb --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/values/styles.xml b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..d460d1e --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/plugins/toaster_utils/toaster_utils/example/android/app/src/profile/AndroidManifest.xml b/plugins/toaster_utils/toaster_utils/example/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..f880684 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + + diff --git a/plugins/toaster_utils/toaster_utils/example/android/build.gradle.kts b/plugins/toaster_utils/toaster_utils/example/android/build.gradle.kts new file mode 100644 index 0000000..7089ee8 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/android/build.gradle.kts @@ -0,0 +1,25 @@ +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) +} \ No newline at end of file diff --git a/plugins/toaster_utils/toaster_utils/example/android/gradle.properties b/plugins/toaster_utils/toaster_utils/example/android/gradle.properties new file mode 100644 index 0000000..f018a61 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError +android.useAndroidX=true +android.enableJetifier=true diff --git a/plugins/toaster_utils/toaster_utils/example/android/gradle/wrapper/gradle-wrapper.properties b/plugins/toaster_utils/toaster_utils/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..712d1d5 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-all.zip +networkTimeout=10000 +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/plugins/toaster_utils/toaster_utils/example/android/settings.gradle.kts b/plugins/toaster_utils/toaster_utils/example/android/settings.gradle.kts new file mode 100644 index 0000000..3915365 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/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.12.0" apply false + id("org.jetbrains.kotlin.android") version "2.2.10" apply false +} + +include(":app") \ No newline at end of file diff --git a/plugins/toaster_utils/toaster_utils/example/flows/test_platform_name.yaml b/plugins/toaster_utils/toaster_utils/example/flows/test_platform_name.yaml new file mode 100644 index 0000000..6fcb0bb --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/flows/test_platform_name.yaml @@ -0,0 +1,4 @@ +description: Test if plugin returns correct platform name +--- +- pressOn: "Get Platform Name" +- checkPlatformName: \ No newline at end of file diff --git a/plugins/toaster_utils/toaster_utils/example/fluttium.yaml b/plugins/toaster_utils/toaster_utils/example/fluttium.yaml new file mode 100644 index 0000000..bb353a6 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/fluttium.yaml @@ -0,0 +1,6 @@ +environment: + fluttium: ">=0.1.0 <1.0.0" + +actions: + check_platform_name: + path: actions/check_platform_name diff --git a/plugins/toaster_utils/toaster_utils/example/integration_test/app_test.dart b/plugins/toaster_utils/toaster_utils/example/integration_test/app_test.dart new file mode 100644 index 0000000..a221cea --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/integration_test/app_test.dart @@ -0,0 +1,28 @@ +import 'dart:io'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; + +import 'package:toaster_utils_example/main.dart' as app; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('E2E', () { + testWidgets('getPlatformName', (tester) async { + app.main(); + await tester.pumpAndSettle(); + await tester.tap(find.text('Get Platform Name')); + await tester.pumpAndSettle(); + final expected = expectedPlatformName(); + await tester.ensureVisible(find.text('Platform Name: $expected')); + }); + }); +} + +String expectedPlatformName() { + if (Platform.isAndroid) return 'Android'; + if (Platform.isIOS) return 'iOS'; + if (Platform.isMacOS) return 'MacOS'; + throw UnsupportedError('Unsupported platform ${Platform.operatingSystem}'); +} diff --git a/plugins/toaster_utils/toaster_utils/example/ios/.gitignore b/plugins/toaster_utils/toaster_utils/example/ios/.gitignore new file mode 100644 index 0000000..7a7f987 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Flutter/AppFrameworkInfo.plist b/plugins/toaster_utils/toaster_utils/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..391a902 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + + diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Flutter/Debug.xcconfig b/plugins/toaster_utils/toaster_utils/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..ec97fc6 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Flutter/Release.xcconfig b/plugins/toaster_utils/toaster_utils/example/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..c4855bf --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Podfile b/plugins/toaster_utils/toaster_utils/example/ios/Podfile new file mode 100644 index 0000000..e72e0b4 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Podfile @@ -0,0 +1,41 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '13.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! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcodeproj/project.pbxproj b/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..96a80eb --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,558 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 6578EEA2C83B6388B886968C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D6986157739D9687AB6AFD6 /* 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 */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + 97C147101CF9000F007C117D /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97C147111CF9000F007C117D /* SceneDelegate.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* 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 = ""; }; + 1D6986157739D9687AB6AFD6 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; 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 = ""; }; + 92B43DD0AD58E6356D15892C /* 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; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 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 = ""; }; + 97C147111CF9000F007C117D /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + C32DC939DE75A0BDF7B647A4 /* 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 = ""; }; + FC95DB849BF641CAD26B8123 /* 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 = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6578EEA2C83B6388B886968C /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 71A9A1607E036E391BA6A301 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1D6986157739D9687AB6AFD6 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 9567CFDD8F7714B0D403105A /* Pods */ = { + isa = PBXGroup; + children = ( + 92B43DD0AD58E6356D15892C /* Pods-Runner.debug.xcconfig */, + C32DC939DE75A0BDF7B647A4 /* Pods-Runner.release.xcconfig */, + FC95DB849BF641CAD26B8123 /* Pods-Runner.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 9567CFDD8F7714B0D403105A /* Pods */, + 71A9A1607E036E391BA6A301 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 97C147111CF9000F007C117D /* SceneDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 0266454444A641F4EB110FC5 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 40760E14F3E664153DAD2ABC /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 0266454444A641F4EB110FC5 /* [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; + }; + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 40760E14F3E664153DAD2ABC /* [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; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 97C147101CF9000F007C117D /* SceneDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 55PNJ85CXL; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.mars3142.plugin.toaster-utils.example"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 55PNJ85CXL; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.mars3142.plugin.toaster-utils.example"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 55PNJ85CXL; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.mars3142.plugin.toaster-utils.example"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..c53e2b3 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/AppDelegate.swift b/plugins/toaster_utils/toaster_utils/example/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..6bea110 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner/AppDelegate.swift @@ -0,0 +1,16 @@ +import UIKit +import Flutter + +@main +@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } + + func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) { + GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry) + } +} diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..dc9ada4 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..28c6bf0 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..f091b6b Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cde121 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..d0ef06e Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..dcdc230 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..c8f9ed8 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..75b2d16 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..c4df70d Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..6a84f41 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..d0e1f58 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Base.lproj/Main.storyboard b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Info.plist b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Info.plist new file mode 100644 index 0000000..c548804 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Info.plist @@ -0,0 +1,72 @@ + + + + + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Example + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneClassName + UIWindowScene + UISceneConfigurationName + flutter + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/Runner-Bridging-Header.h b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/plugins/toaster_utils/toaster_utils/example/ios/Runner/SceneDelegate.swift b/plugins/toaster_utils/toaster_utils/example/ios/Runner/SceneDelegate.swift new file mode 100644 index 0000000..ee0e4cf --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/ios/Runner/SceneDelegate.swift @@ -0,0 +1,6 @@ +import Flutter +import UIKit + +class SceneDelegate: FlutterSceneDelegate { + // FlutterSceneDelegate handles all scene lifecycle events +} diff --git a/plugins/toaster_utils/toaster_utils/example/lib/main.dart b/plugins/toaster_utils/toaster_utils/example/lib/main.dart new file mode 100644 index 0000000..65506d3 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/lib/main.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; +import 'package:toaster_utils/toaster_utils.dart'; + +void main() => runApp(const MyApp()); + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return const MaterialApp(home: HomePage()); + } +} + +class HomePage extends StatefulWidget { + const HomePage({super.key}); + + @override + State createState() => _HomePageState(); +} + +class _HomePageState extends State { + String? _platformName; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('ToasterUtils Example'), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (_platformName == null) + const SizedBox.shrink() + else + Text( + 'Platform Name: $_platformName', + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 16), + ElevatedButton( + onPressed: () async { + if (!context.mounted) return; + try { + final result = await getPlatformName(); + setState(() => _platformName = result); + } on Exception catch (error) { + if (!context.mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + backgroundColor: Theme.of(context).primaryColor, + content: Text('$error'), + ), + ); + } + }, + child: const Text('Get Platform Name'), + ), + ], + ), + ), + ); + } +} diff --git a/plugins/toaster_utils/toaster_utils/example/macos/.gitignore b/plugins/toaster_utils/toaster_utils/example/macos/.gitignore new file mode 100644 index 0000000..746adbb --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Flutter/Flutter-Debug.xcconfig b/plugins/toaster_utils/toaster_utils/example/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 0000000..4b81f9b --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Flutter/Flutter-Release.xcconfig b/plugins/toaster_utils/toaster_utils/example/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 0000000..5caa9d1 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Podfile b/plugins/toaster_utils/toaster_utils/example/macos/Podfile new file mode 100644 index 0000000..9ec46f8 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Podfile @@ -0,0 +1,40 @@ +platform :osx, '10.15' + +# 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! + use_modular_headers! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner.xcodeproj/project.pbxproj b/plugins/toaster_utils/toaster_utils/example/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..5f3cd32 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,633 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + 8056B9E1FA9168F10A6879E3 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF88737E4227AF4483D73A72 /* Pods_Runner.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 082C0DA75B3DC0A853AE53D1 /* 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 = ""; }; + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 604426B4C55353DB93E63726 /* 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 = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 7CC079B1077C0BC3449BC7C1 /* 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 = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + BF88737E4227AF4483D73A72 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8056B9E1FA9168F10A6879E3 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 0EEA7CE099CD931C8BF18132 /* Pods */ = { + isa = PBXGroup; + children = ( + 604426B4C55353DB93E63726 /* Pods-Runner.debug.xcconfig */, + 7CC079B1077C0BC3449BC7C1 /* Pods-Runner.release.xcconfig */, + 082C0DA75B3DC0A853AE53D1 /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + 0EEA7CE099CD931C8BF18132 /* Pods */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* example.app */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + BF88737E4227AF4483D73A72 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + BA51270DFB65A51AF6561C86 /* [CP] Check Pods Manifest.lock */, + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + 01C1BE47E39E4FF65E75DFDD /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* example.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 01C1BE47E39E4FF65E75DFDD /* [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; + }; + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; + BA51270DFB65A51AF6561C86 /* [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; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/plugins/toaster_utils/toaster_utils/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/plugins/toaster_utils/toaster_utils/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..12076c8 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/plugins/toaster_utils/toaster_utils/example/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/plugins/toaster_utils/toaster_utils/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/AppDelegate.swift b/plugins/toaster_utils/toaster_utils/example/macos/Runner/AppDelegate.swift new file mode 100644 index 0000000..b3c1761 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import Cocoa +import FlutterMacOS + +@main +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } + + override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } +} diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a2ec33f --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 0000000..82b6f9d Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 0000000..13b35eb Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 0000000..0a3f5fa Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 0000000..bdb5722 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 0000000..f083318 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 0000000..326c0e7 Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 0000000..2f1632c Binary files /dev/null and b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/Base.lproj/MainMenu.xib b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 0000000..80e867a --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/Configs/AppInfo.xcconfig b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 0000000..e253836 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = example + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = com.example.myplugin.example + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2023 org.mars3142. All rights reserved. diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/Configs/Debug.xcconfig b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 0000000..36b0fd9 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/Configs/Release.xcconfig b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 0000000..dff4f49 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/Configs/Warnings.xcconfig b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 0000000..42bcbf4 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/DebugProfile.entitlements b/plugins/toaster_utils/toaster_utils/example/macos/Runner/DebugProfile.entitlements new file mode 100644 index 0000000..dddb8a3 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/Info.plist b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Info.plist new file mode 100644 index 0000000..4789daa --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/MainFlutterWindow.swift b/plugins/toaster_utils/toaster_utils/example/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 0000000..2722837 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController.init() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/plugins/toaster_utils/toaster_utils/example/macos/Runner/Release.entitlements b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Release.entitlements new file mode 100644 index 0000000..852fa1a --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/plugins/toaster_utils/toaster_utils/example/pubspec.yaml b/plugins/toaster_utils/toaster_utils/example/pubspec.yaml new file mode 100644 index 0000000..673ee7d --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/pubspec.yaml @@ -0,0 +1,30 @@ +name: toaster_utils_example +description: Demonstrates how to use the toaster_utils plugin. +version: 0.1.0+1 +publish_to: none + +environment: + sdk: ^3.11.0 + +dependencies: + flutter: + sdk: flutter + toaster_utils: + # When depending on this package from a real application you should use: + # toaster_utils: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. + path: ../ + +dev_dependencies: + flutter_driver: + sdk: flutter + flutter_test: + sdk: flutter + integration_test: + sdk: flutter + very_good_analysis: ^10.2.0 + +flutter: + uses-material-design: true diff --git a/plugins/toaster_utils/toaster_utils/example/test_driver/integration_test.dart b/plugins/toaster_utils/toaster_utils/example/test_driver/integration_test.dart new file mode 100644 index 0000000..b38629c --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/example/test_driver/integration_test.dart @@ -0,0 +1,3 @@ +import 'package:integration_test/integration_test_driver.dart'; + +Future main() => integrationDriver(); diff --git a/plugins/toaster_utils/toaster_utils/lib/toaster_utils.dart b/plugins/toaster_utils/toaster_utils/lib/toaster_utils.dart new file mode 100644 index 0000000..ae5770e --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/lib/toaster_utils.dart @@ -0,0 +1,11 @@ +import 'package:toaster_utils_platform_interface/toaster_utils_platform_interface.dart'; + +ToasterUtilsPlatform get _platform => + ToasterUtilsPlatform.instance; + +/// Returns the name of the current platform. +Future getPlatformName() async { + final platformName = await _platform.getPlatformName(); + if (platformName == null) throw Exception('Unable to get platform name.'); + return platformName; +} diff --git a/plugins/toaster_utils/toaster_utils/pubspec.yaml b/plugins/toaster_utils/toaster_utils/pubspec.yaml new file mode 100644 index 0000000..40e6f29 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/pubspec.yaml @@ -0,0 +1,38 @@ +name: toaster_utils +description: A Very Good Project created by Very Good CLI. +version: 0.1.0+1 +publish_to: none + +environment: + sdk: ^3.11.0 + +flutter: + plugin: + platforms: + android: + default_package: toaster_utils_android + ios: + default_package: toaster_utils_ios + macos: + default_package: toaster_utils_macos + +dependencies: + flutter: + sdk: flutter + toaster_utils_android: + path: ../toaster_utils_android + toaster_utils_ios: + path: ../toaster_utils_ios + toaster_utils_macos: + path: ../toaster_utils_macos + toaster_utils_platform_interface: + path: ../toaster_utils_platform_interface + +dev_dependencies: + flutter_test: + sdk: flutter + mocktail: ^1.0.5 + plugin_platform_interface: ^2.1.8 + very_good_analysis: ^10.2.0 + +resolution: workspace diff --git a/plugins/toaster_utils/toaster_utils/test/toaster_utils_test.dart b/plugins/toaster_utils/toaster_utils/test/toaster_utils_test.dart new file mode 100644 index 0000000..4a31f96 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils/test/toaster_utils_test.dart @@ -0,0 +1,51 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import 'package:toaster_utils/toaster_utils.dart'; +import 'package:toaster_utils_platform_interface/toaster_utils_platform_interface.dart'; + +class MockToasterUtilsPlatform extends Mock + with MockPlatformInterfaceMixin + implements ToasterUtilsPlatform {} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group(ToasterUtilsPlatform, () { + late ToasterUtilsPlatform + toasterUtilsPlatform; + + setUp(() { + toasterUtilsPlatform = + MockToasterUtilsPlatform(); + ToasterUtilsPlatform.instance = + toasterUtilsPlatform; + }); + + group('getPlatformName', () { + test( + 'returns correct name when platform implementation exists', + () async { + const platformName = '__test_platform__'; + when( + () => toasterUtilsPlatform.getPlatformName(), + ).thenAnswer((_) async => platformName); + + final actualPlatformName = await getPlatformName(); + expect(actualPlatformName, equals(platformName)); + }, + ); + + test( + 'throws exception when platform implementation is missing', + () async { + when( + () => toasterUtilsPlatform.getPlatformName(), + ).thenAnswer((_) async => null); + + expect(getPlatformName, throwsException); + }, + ); + }); + }); +} diff --git a/plugins/toaster_utils/toaster_utils_android/README.md b/plugins/toaster_utils/toaster_utils_android/README.md new file mode 100644 index 0000000..dde84d2 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_android/README.md @@ -0,0 +1,14 @@ +# toaster_utils_android + +[![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] + +The Android implementation of `toaster_utils`. + +## Usage + +This package is [endorsed][endorsed_link], which means you can simply use `toaster_utils` +normally. This package will be automatically included in your app when you do. + +[endorsed_link]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg +[very_good_analysis_link]: https://pub.dev/packages/very_good_analysis \ No newline at end of file diff --git a/plugins/toaster_utils/toaster_utils_android/analysis_options.yaml b/plugins/toaster_utils/toaster_utils_android/analysis_options.yaml new file mode 100644 index 0000000..c5dcf88 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_android/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:very_good_analysis/analysis_options.yaml +analyzer: + exclude: + - "**/*.g.dart" diff --git a/plugins/toaster_utils/toaster_utils_android/android/.gitignore b/plugins/toaster_utils/toaster_utils_android/android/.gitignore new file mode 100644 index 0000000..71642f1 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_android/android/.gitignore @@ -0,0 +1,9 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +.cxx \ No newline at end of file diff --git a/plugins/toaster_utils/toaster_utils_android/android/build.gradle b/plugins/toaster_utils/toaster_utils_android/android/build.gradle new file mode 100644 index 0000000..51da051 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_android/android/build.gradle @@ -0,0 +1,57 @@ +plugins { + id "com.android.library" + id "kotlin-android" +} + +group 'org.mars3142' +version '1.0-SNAPSHOT' + +allprojects { + repositories { + google() + mavenCentral() + } +} + +android { + if (project.android.hasProperty("namespace")) { + namespace 'org.mars3142' + } + + compileSdk 34 + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = '1.8' + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + test.java.srcDirs += 'src/test/kotlin' + } + + defaultConfig { + minSdkVersion 19 + } + + dependencies { + testImplementation 'org.jetbrains.kotlin:kotlin-test' + testImplementation 'org.mockito:mockito-core:5.0.0' + } + + testOptions { + unitTests.all { + useJUnitPlatform() + + testLogging { + events "passed", "skipped", "failed", "standardOut", "standardError" + outputs.upToDateWhen {false} + showStandardStreams = true + } + } + } +} \ No newline at end of file diff --git a/plugins/toaster_utils/toaster_utils_android/android/settings.gradle.kts b/plugins/toaster_utils/toaster_utils_android/android/settings.gradle.kts new file mode 100644 index 0000000..cf0e86d --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_android/android/settings.gradle.kts @@ -0,0 +1,6 @@ +rootProject.name = 'toaster_utils_android' + +plugins { + id("com.android.library") version "8.12.0" apply false + id("org.jetbrains.kotlin.android") version "2.2.10" apply false +} \ No newline at end of file diff --git a/plugins/toaster_utils/toaster_utils_android/android/src/main/AndroidManifest.xml b/plugins/toaster_utils/toaster_utils_android/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000..c4e6c98 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_android/android/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/plugins/toaster_utils/toaster_utils_android/android/src/main/kotlin/org/mars3142/Messages.g.kt b/plugins/toaster_utils/toaster_utils_android/android/src/main/kotlin/org/mars3142/Messages.g.kt new file mode 100644 index 0000000..7437186 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_android/android/src/main/kotlin/org/mars3142/Messages.g.kt @@ -0,0 +1,93 @@ +// Copyright (c) 2026, Org Mars3142 +// Autogenerated from Pigeon (v26.3.4), do not edit directly. +// See also: https://pub.dev/packages/pigeon +@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass") + + +import android.util.Log +import io.flutter.plugin.common.BasicMessageChannel +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.EventChannel +import io.flutter.plugin.common.MessageCodec +import io.flutter.plugin.common.StandardMethodCodec +import io.flutter.plugin.common.StandardMessageCodec +import java.io.ByteArrayOutputStream +import java.nio.ByteBuffer +private object MessagesPigeonUtils { + + fun wrapResult(result: Any?): List { + return listOf(result) + } + + fun wrapError(exception: Throwable): List { + return if (exception is FlutterError) { + listOf( + exception.code, + exception.message, + exception.details + ) + } else { + listOf( + exception.javaClass.simpleName, + exception.toString(), + "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception) + ) + } + } +} + +/** + * Error class for passing custom error details to Flutter via a thrown PlatformException. + * @property code The error code. + * @property message The error message. + * @property details The error details. Must be a datatype supported by the api codec. + */ +class FlutterError ( + val code: String, + override val message: String? = null, + val details: Any? = null +) : RuntimeException() +private open class MessagesPigeonCodec : StandardMessageCodec() { + override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { + return super.readValueOfType(type, buffer) + } + override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { + super.writeValue(stream, value) + } +} + + +/** Generated interface from Pigeon that represents a handler of messages from Flutter. */ +interface ToasterUtilsApi { + fun getPlatformName(callback: (Result) -> Unit) + + companion object { + /** The codec used by ToasterUtilsApi. */ + val codec: MessageCodec by lazy { + MessagesPigeonCodec() + } + /** Sets up an instance of `ToasterUtilsApi` to handle messages through the `binaryMessenger`. */ + @JvmOverloads + fun setUp(binaryMessenger: BinaryMessenger, api: ToasterUtilsApi?, messageChannelSuffix: String = "") { + val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getPlatformName$separatedMessageChannelSuffix", codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + api.getPlatformName{ result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(MessagesPigeonUtils.wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(MessagesPigeonUtils.wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + } + } +} diff --git a/plugins/toaster_utils/toaster_utils_android/android/src/main/kotlin/org/mars3142/ToasterUtilsPlugin.kt b/plugins/toaster_utils/toaster_utils_android/android/src/main/kotlin/org/mars3142/ToasterUtilsPlugin.kt new file mode 100644 index 0000000..06bbd0a --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_android/android/src/main/kotlin/org/mars3142/ToasterUtilsPlugin.kt @@ -0,0 +1,22 @@ +package org.mars3142 + +import ToasterUtilsApi +import io.flutter.embedding.engine.plugins.FlutterPlugin + +class ToasterUtilsPlugin : FlutterPlugin, ToasterUtilsApi { + companion object { + private const val TAG = "ToasterUtilsPlugin" + } + + override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { + ToasterUtilsApi.setUp(binding.binaryMessenger, this) + } + + override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { + ToasterUtilsApi.setUp(binding.binaryMessenger, null) + } + + override fun getPlatformName(callback: (Result) -> Unit) { + callback(Result.success("Android ${android.os.Build.VERSION.RELEASE}")) + } +} \ No newline at end of file diff --git a/plugins/toaster_utils/toaster_utils_android/lib/src/messages.g.dart b/plugins/toaster_utils/toaster_utils_android/lib/src/messages.g.dart new file mode 100644 index 0000000..b5af842 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_android/lib/src/messages.g.dart @@ -0,0 +1,92 @@ +// Copyright (c) 2026, Org Mars3142 +// Autogenerated from Pigeon (v26.3.4), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: unused_import, unused_shown_name +// ignore_for_file: type=lint + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List; + +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart' show immutable, protected, visibleForTesting; + +Object? _extractReplyValueOrThrow( + List? replyList, + String channelName, { + required bool isNullValid, +}) { + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (!isNullValid && (replyList.isNotEmpty && replyList[0] == null)) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } + return replyList.firstOrNull; +} + + + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + default: + return super.readValueOfType(type, buffer); + } + } +} + +class ToasterUtilsApi { + /// Constructor for [ToasterUtilsApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + ToasterUtilsApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + Future getPlatformName() async { + final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getPlatformName$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: true, + ) + ; + return pigeonVar_replyValue as String?; + } +} diff --git a/plugins/toaster_utils/toaster_utils_android/lib/toaster_utils_android.dart b/plugins/toaster_utils/toaster_utils_android/lib/toaster_utils_android.dart new file mode 100644 index 0000000..56ac84a --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_android/lib/toaster_utils_android.dart @@ -0,0 +1,28 @@ +import 'package:flutter/foundation.dart'; +import 'package:toaster_utils_android/src/messages.g.dart'; +import 'package:toaster_utils_platform_interface/toaster_utils_platform_interface.dart'; + +/// {@template toaster_utils_android} +/// The Android implementation of [ToasterUtilsPlatform]. +/// {@endtemplate} +class ToasterUtilsAndroid extends ToasterUtilsPlatform { + /// {@macro toaster_utils_android} + ToasterUtilsAndroid({ + @visibleForTesting ToasterUtilsApi? api, + }) : api = api ?? ToasterUtilsApi(); + + /// The API used to interact with the native platform. + final ToasterUtilsApi api; + + /// Registers this class as the default instance of + /// [ToasterUtilsPlatform]. + static void registerWith() { + ToasterUtilsPlatform.instance = + ToasterUtilsAndroid(); + } + + @override + Future getPlatformName() { + return api.getPlatformName(); + } +} diff --git a/plugins/toaster_utils/toaster_utils_android/pigeons/copyright.txt b/plugins/toaster_utils/toaster_utils_android/pigeons/copyright.txt new file mode 100644 index 0000000..3d7f53c --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_android/pigeons/copyright.txt @@ -0,0 +1 @@ +Copyright (c) 2026, Org Mars3142 diff --git a/plugins/toaster_utils/toaster_utils_android/pigeons/messages.dart b/plugins/toaster_utils/toaster_utils_android/pigeons/messages.dart new file mode 100644 index 0000000..89a8682 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_android/pigeons/messages.dart @@ -0,0 +1,19 @@ +// ToasterUtilsApi must be abstract. +// ignore_for_file: one_member_abstracts + +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon( + PigeonOptions( + dartOut: 'lib/src/messages.g.dart', + dartPackageName: 'toaster_utils', + kotlinOut: 'android/src/main/kotlin/org/mars3142/Messages.g.kt', + kotlinOptions: KotlinOptions(), + copyrightHeader: 'pigeons/copyright.txt', + ), +) +@HostApi() +abstract class ToasterUtilsApi { + @async + String? getPlatformName(); +} diff --git a/plugins/toaster_utils/toaster_utils_android/pubspec.yaml b/plugins/toaster_utils/toaster_utils_android/pubspec.yaml new file mode 100644 index 0000000..ac87745 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_android/pubspec.yaml @@ -0,0 +1,32 @@ +name: toaster_utils_android +description: Android implementation of the toaster_utils plugin +version: 0.1.0+1 +publish_to: none + +environment: + sdk: ^3.11.0 + +flutter: + plugin: + implements: toaster_utils + platforms: + android: + package: org.mars3142 + pluginClass: ToasterUtilsPlugin + dartPluginClass: ToasterUtilsAndroid + +dependencies: + flutter: + sdk: flutter + toaster_utils_platform_interface: + path: ../toaster_utils_platform_interface + +dev_dependencies: + flutter_test: + sdk: flutter + mocktail: ^1.0.4 + pigeon: ^26.0.2 + plugin_platform_interface: ^2.1.8 + very_good_analysis: ^10.2.0 + +resolution: workspace diff --git a/plugins/toaster_utils/toaster_utils_android/test/toaster_utils_android_test.dart b/plugins/toaster_utils/toaster_utils_android/test/toaster_utils_android_test.dart new file mode 100644 index 0000000..5dc5bac --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_android/test/toaster_utils_android_test.dart @@ -0,0 +1,42 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:toaster_utils_android/src/messages.g.dart'; +import 'package:toaster_utils_android/toaster_utils_android.dart'; +import 'package:toaster_utils_platform_interface/toaster_utils_platform_interface.dart'; + +class _MockToasterUtilsApi extends Mock + implements ToasterUtilsApi {} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group(ToasterUtilsAndroid, () { + const kPlatformName = 'Android'; + late ToasterUtilsAndroid toasterUtils; + late ToasterUtilsApi api; + + setUp(() { + api = _MockToasterUtilsApi(); + toasterUtils = ToasterUtilsAndroid(api: api); + }); + + test('can be registered', () { + ToasterUtilsAndroid.registerWith(); + expect( + ToasterUtilsPlatform.instance, + isA(), + ); + }); + + test('getPlatformName returns correct name', () async { + when(api.getPlatformName).thenAnswer((_) async => kPlatformName); + + await expectLater( + toasterUtils.getPlatformName(), + completion(equals(kPlatformName)), + ); + + verify(api.getPlatformName).called(1); + }); + }); +} diff --git a/plugins/toaster_utils/toaster_utils_ios/.gitignore b/plugins/toaster_utils/toaster_utils_ios/.gitignore new file mode 100644 index 0000000..ea8e0cb --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_ios/.gitignore @@ -0,0 +1,2 @@ +.build/ +.swiftpm/ \ No newline at end of file diff --git a/plugins/toaster_utils/toaster_utils_ios/README.md b/plugins/toaster_utils/toaster_utils_ios/README.md new file mode 100644 index 0000000..25887ac --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_ios/README.md @@ -0,0 +1,14 @@ +# toaster_utils_ios + +[![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] + +The ios implementation of `toaster_utils`. + +## Usage + +This package is [endorsed][endorsed_link], which means you can simply use `toaster_utils` +normally. This package will be automatically included in your app when you do. + +[endorsed_link]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg +[very_good_analysis_link]: https://pub.dev/packages/very_good_analysis \ No newline at end of file diff --git a/plugins/toaster_utils/toaster_utils_ios/analysis_options.yaml b/plugins/toaster_utils/toaster_utils_ios/analysis_options.yaml new file mode 100644 index 0000000..c5dcf88 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_ios/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:very_good_analysis/analysis_options.yaml +analyzer: + exclude: + - "**/*.g.dart" diff --git a/plugins/toaster_utils/toaster_utils_ios/ios/toaster_utils_ios.podspec b/plugins/toaster_utils/toaster_utils_ios/ios/toaster_utils_ios.podspec new file mode 100644 index 0000000..1a5154e --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_ios/ios/toaster_utils_ios.podspec @@ -0,0 +1,20 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# +Pod::Spec.new do |s| + s.name = 'toaster_utils_ios' + s.version = '0.0.1' + s.summary = 'An iOS implementation of the toaster_utils plugin.' + s.description = <<-DESC + An iOS implementation of the toaster_utils plugin. + DESC + s.homepage = 'http://example.com' + s.license = { :type => 'BSD', :file => '../LICENSE' } + s.author = { 'Org Mars3142' => 'email@example.com' } + s.source = { :path => '.' } + s.source_files = 'toaster_utils_ios/Sources/**/*.swift' + s.dependency 'Flutter' + s.platform = :ios, '13.0' + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } + s.swift_version = '6.1' +end diff --git a/plugins/toaster_utils/toaster_utils_ios/ios/toaster_utils_ios/Package.swift b/plugins/toaster_utils/toaster_utils_ios/ios/toaster_utils_ios/Package.swift new file mode 100644 index 0000000..986a7dd --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_ios/ios/toaster_utils_ios/Package.swift @@ -0,0 +1,33 @@ +// swift-tools-version: 6.1 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "toaster_utils_ios", + platforms: [ + .iOS("13.0"), + ], + products: [ + .library(name: "toaster-utils-ios", targets: ["toaster_utils_ios"]) + ], + dependencies: [], + targets: [ + .target( + name: "toaster_utils_ios", + dependencies: [], + resources: [ + // TODO: If your plugin requires a privacy manifest + // (e.g. if it uses any required reason APIs), update the PrivacyInfo.xcprivacy file + // to describe your plugin's privacy impact, and then uncomment this line. + // For more information, see: + // https://developer.apple.com/documentation/bundleresources/privacy_manifest_files + // .process("PrivacyInfo.xcprivacy"), + + // TODO: If you have other resources that need to be bundled with your plugin, refer to + // the following instructions to add them: + // https://developer.apple.com/documentation/xcode/bundling-resources-with-a-swift-package + ] + ) + ] +) \ No newline at end of file diff --git a/plugins/toaster_utils/toaster_utils_ios/ios/toaster_utils_ios/Sources/toaster_utils_ios/Messages.g.swift b/plugins/toaster_utils/toaster_utils_ios/ios/toaster_utils_ios/Sources/toaster_utils_ios/Messages.g.swift new file mode 100644 index 0000000..d8d079b --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_ios/ios/toaster_utils_ios/Sources/toaster_utils_ios/Messages.g.swift @@ -0,0 +1,117 @@ +// Copyright (c) 2026, Org mars3142 +// Autogenerated from Pigeon (v26.3.4), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +import Foundation + +#if os(iOS) + import Flutter +#elseif os(macOS) + import FlutterMacOS +#else + #error("Unsupported platform.") +#endif + +/// Error class for passing custom error details to Dart side. +final class PigeonError: Error { + let code: String + let message: String? + let details: Sendable? + + init(code: String, message: String?, details: Sendable?) { + self.code = code + self.message = message + self.details = details + } + + var localizedDescription: String { + return + "PigeonError(code: \(code), message: \(message ?? ""), details: \(details ?? "")" + } +} + +private func wrapResult(_ result: Any?) -> [Any?] { + return [result] +} + +private func wrapError(_ error: Any) -> [Any?] { + if let pigeonError = error as? PigeonError { + return [ + pigeonError.code, + pigeonError.message, + pigeonError.details, + ] + } + if let flutterError = error as? FlutterError { + return [ + flutterError.code, + flutterError.message, + flutterError.details, + ] + } + return [ + "\(error)", + "\(Swift.type(of: error))", + "Stacktrace: \(Thread.callStackSymbols)", + ] +} + +private func isNullish(_ value: Any?) -> Bool { + return value is NSNull || value == nil +} + +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? +} + + +private class MessagesPigeonCodecReader: FlutterStandardReader { +} + +private class MessagesPigeonCodecWriter: FlutterStandardWriter { +} + +private class MessagesPigeonCodecReaderWriter: FlutterStandardReaderWriter { + override func reader(with data: Data) -> FlutterStandardReader { + return MessagesPigeonCodecReader(data: data) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return MessagesPigeonCodecWriter(data: data) + } +} + +class MessagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable { + static let shared = MessagesPigeonCodec(readerWriter: MessagesPigeonCodecReaderWriter()) +} + + +/// Generated protocol from Pigeon that represents a handler of messages from Flutter. +protocol ToasterUtilsApi { + func getPlatformName(completion: @escaping (Result) -> Void) +} + +/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. +class ToasterUtilsApiSetup { + static var codec: FlutterStandardMessageCodec { MessagesPigeonCodec.shared } + /// Sets up an instance of `ToasterUtilsApi` to handle messages through the `binaryMessenger`. + static func setUp(binaryMessenger: FlutterBinaryMessenger, api: ToasterUtilsApi?, messageChannelSuffix: String = "") { + let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" + let getPlatformNameChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getPlatformName\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getPlatformNameChannel.setMessageHandler { _, reply in + api.getPlatformName { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + getPlatformNameChannel.setMessageHandler(nil) + } + } +} diff --git a/plugins/toaster_utils/toaster_utils_ios/ios/toaster_utils_ios/Sources/toaster_utils_ios/ToasterUtilsPlugin.swift b/plugins/toaster_utils/toaster_utils_ios/ios/toaster_utils_ios/Sources/toaster_utils_ios/ToasterUtilsPlugin.swift new file mode 100644 index 0000000..6614c35 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_ios/ios/toaster_utils_ios/Sources/toaster_utils_ios/ToasterUtilsPlugin.swift @@ -0,0 +1,14 @@ +import Flutter + +public class ToasterUtilsPlugin: NSObject, FlutterPlugin, ToasterUtilsApi { + public static func register(with registrar: FlutterPluginRegistrar) { + let binaryMessenger = registrar.messenger() + let instance = ToasterUtilsPlugin() + ToasterUtilsApiSetup.setUp(binaryMessenger: binaryMessenger, api: instance) + registrar.publish(instance) + } + + func getPlatformName(completion: @escaping (Result) -> Void) { + completion(.success("iOS")) + } +} diff --git a/plugins/toaster_utils/toaster_utils_ios/lib/src/messages.g.dart b/plugins/toaster_utils/toaster_utils_ios/lib/src/messages.g.dart new file mode 100644 index 0000000..cb97588 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_ios/lib/src/messages.g.dart @@ -0,0 +1,92 @@ +// Copyright (c) 2026, Org mars3142 +// Autogenerated from Pigeon (v26.3.4), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: unused_import, unused_shown_name +// ignore_for_file: type=lint + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List; + +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart' show immutable, protected, visibleForTesting; + +Object? _extractReplyValueOrThrow( + List? replyList, + String channelName, { + required bool isNullValid, +}) { + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (!isNullValid && (replyList.isNotEmpty && replyList[0] == null)) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } + return replyList.firstOrNull; +} + + + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + default: + return super.readValueOfType(type, buffer); + } + } +} + +class ToasterUtilsApi { + /// Constructor for [ToasterUtilsApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + ToasterUtilsApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + Future getPlatformName() async { + final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getPlatformName$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: true, + ) + ; + return pigeonVar_replyValue as String?; + } +} diff --git a/plugins/toaster_utils/toaster_utils_ios/lib/toaster_utils_ios.dart b/plugins/toaster_utils/toaster_utils_ios/lib/toaster_utils_ios.dart new file mode 100644 index 0000000..b72d389 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_ios/lib/toaster_utils_ios.dart @@ -0,0 +1,28 @@ +import 'package:flutter/foundation.dart'; +import 'package:toaster_utils_ios/src/messages.g.dart'; +import 'package:toaster_utils_platform_interface/toaster_utils_platform_interface.dart'; + +/// {@template toaster_utils_ios} +/// The iOS implementation of [ToasterUtilsPlatform]. +/// {@endtemplate} +class ToasterUtilsIOS extends ToasterUtilsPlatform { + /// {@macro toaster_utils_ios} + ToasterUtilsIOS({ + @visibleForTesting ToasterUtilsApi? api, + }) : api = api ?? ToasterUtilsApi(); + + /// The API used to interact with the native platform. + final ToasterUtilsApi api; + + /// Registers this class as the default instance of + /// [ToasterUtilsPlatform]. + static void registerWith() { + ToasterUtilsPlatform.instance = + ToasterUtilsIOS(); + } + + @override + Future getPlatformName() { + return api.getPlatformName(); + } +} diff --git a/plugins/toaster_utils/toaster_utils_ios/pigeons/copyright.txt b/plugins/toaster_utils/toaster_utils_ios/pigeons/copyright.txt new file mode 100644 index 0000000..7a8c0eb --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_ios/pigeons/copyright.txt @@ -0,0 +1 @@ +Copyright (c) 2026, Org mars3142 diff --git a/plugins/toaster_utils/toaster_utils_ios/pigeons/messages.dart b/plugins/toaster_utils/toaster_utils_ios/pigeons/messages.dart new file mode 100644 index 0000000..3497af0 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_ios/pigeons/messages.dart @@ -0,0 +1,19 @@ +// ToasterUtilsApi must be abstract. +// ignore_for_file: one_member_abstracts + +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon( + PigeonOptions( + dartOut: 'lib/src/messages.g.dart', + dartPackageName: 'toaster_utils', + swiftOut: 'ios/toaster_utils_ios/Sources/toaster_utils_ios/Messages.g.swift', + swiftOptions: SwiftOptions(), + copyrightHeader: 'pigeons/copyright.txt', + ), +) +@HostApi() +abstract class ToasterUtilsApi { + @async + String? getPlatformName(); +} diff --git a/plugins/toaster_utils/toaster_utils_ios/pubspec.yaml b/plugins/toaster_utils/toaster_utils_ios/pubspec.yaml new file mode 100644 index 0000000..b5f115c --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_ios/pubspec.yaml @@ -0,0 +1,31 @@ +name: toaster_utils_ios +description: iOS implementation of the toaster_utils plugin +version: 0.1.0+1 +publish_to: none + +environment: + sdk: ^3.11.0 + +flutter: + plugin: + implements: toaster_utils + platforms: + ios: + pluginClass: ToasterUtilsPlugin + dartPluginClass: ToasterUtilsIOS + +dependencies: + flutter: + sdk: flutter + toaster_utils_platform_interface: + path: ../toaster_utils_platform_interface + +dev_dependencies: + flutter_test: + sdk: flutter + mocktail: ^1.0.4 + pigeon: ^26.0.2 + plugin_platform_interface: ^2.1.8 + very_good_analysis: ^10.2.0 + +resolution: workspace diff --git a/plugins/toaster_utils/toaster_utils_ios/test/toaster_utils_ios_test.dart b/plugins/toaster_utils/toaster_utils_ios/test/toaster_utils_ios_test.dart new file mode 100644 index 0000000..6a70ff6 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_ios/test/toaster_utils_ios_test.dart @@ -0,0 +1,42 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:toaster_utils_ios/src/messages.g.dart'; +import 'package:toaster_utils_ios/toaster_utils_ios.dart'; +import 'package:toaster_utils_platform_interface/toaster_utils_platform_interface.dart'; + +class _MockToasterUtilsApi extends Mock + implements ToasterUtilsApi {} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group(ToasterUtilsIOS, () { + const kPlatformName = 'iOS'; + late ToasterUtilsIOS toasterUtils; + late ToasterUtilsApi api; + + setUp(() { + api = _MockToasterUtilsApi(); + toasterUtils = ToasterUtilsIOS(api: api); + }); + + test('can be registered', () { + ToasterUtilsIOS.registerWith(); + expect( + ToasterUtilsPlatform.instance, + isA(), + ); + }); + + test('getPlatformName returns correct name', () async { + when(api.getPlatformName).thenAnswer((_) async => kPlatformName); + + await expectLater( + toasterUtils.getPlatformName(), + completion(equals(kPlatformName)), + ); + + verify(api.getPlatformName).called(1); + }); + }); +} diff --git a/plugins/toaster_utils/toaster_utils_macos/.gitignore b/plugins/toaster_utils/toaster_utils_macos/.gitignore new file mode 100644 index 0000000..53e92cc --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_macos/.gitignore @@ -0,0 +1,3 @@ +.packages +.flutter-plugins +pubspec.lock diff --git a/plugins/toaster_utils/toaster_utils_macos/README.md b/plugins/toaster_utils/toaster_utils_macos/README.md new file mode 100644 index 0000000..2e85ecb --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_macos/README.md @@ -0,0 +1,14 @@ +# toaster_utils_macos + +[![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] + +The macos implementation of `toaster_utils`. + +## Usage + +This package is [endorsed][endorsed_link], which means you can simply use `toaster_utils` +normally. This package will be automatically included in your app when you do. + +[endorsed_link]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg +[very_good_analysis_link]: https://pub.dev/packages/very_good_analysis diff --git a/plugins/toaster_utils/toaster_utils_macos/analysis_options.yaml b/plugins/toaster_utils/toaster_utils_macos/analysis_options.yaml new file mode 100644 index 0000000..c5dcf88 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_macos/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:very_good_analysis/analysis_options.yaml +analyzer: + exclude: + - "**/*.g.dart" diff --git a/plugins/toaster_utils/toaster_utils_macos/lib/src/messages.g.dart b/plugins/toaster_utils/toaster_utils_macos/lib/src/messages.g.dart new file mode 100644 index 0000000..cb97588 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_macos/lib/src/messages.g.dart @@ -0,0 +1,92 @@ +// Copyright (c) 2026, Org mars3142 +// Autogenerated from Pigeon (v26.3.4), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: unused_import, unused_shown_name +// ignore_for_file: type=lint + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List; + +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart' show immutable, protected, visibleForTesting; + +Object? _extractReplyValueOrThrow( + List? replyList, + String channelName, { + required bool isNullValid, +}) { + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (!isNullValid && (replyList.isNotEmpty && replyList[0] == null)) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } + return replyList.firstOrNull; +} + + + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + default: + return super.readValueOfType(type, buffer); + } + } +} + +class ToasterUtilsApi { + /// Constructor for [ToasterUtilsApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + ToasterUtilsApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + Future getPlatformName() async { + final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getPlatformName$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: true, + ) + ; + return pigeonVar_replyValue as String?; + } +} diff --git a/plugins/toaster_utils/toaster_utils_macos/lib/toaster_utils_macos.dart b/plugins/toaster_utils/toaster_utils_macos/lib/toaster_utils_macos.dart new file mode 100644 index 0000000..e75a1e7 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_macos/lib/toaster_utils_macos.dart @@ -0,0 +1,28 @@ +import 'package:flutter/foundation.dart'; +import 'package:toaster_utils_macos/src/messages.g.dart'; +import 'package:toaster_utils_platform_interface/toaster_utils_platform_interface.dart'; + +/// {@template toaster_utils_macos} +/// The MacOS implementation of [ToasterUtilsPlatform]. +/// {@endtemplate} +class ToasterUtilsMacOS extends ToasterUtilsPlatform { + /// {@macro toaster_utils_macos} + ToasterUtilsMacOS({ + @visibleForTesting ToasterUtilsApi? api, + }) : api = api ?? ToasterUtilsApi(); + + /// The API used to interact with the native platform. + final ToasterUtilsApi api; + + /// Registers this class as the default instance of + /// [ToasterUtilsPlatform]. + static void registerWith() { + ToasterUtilsPlatform.instance = + ToasterUtilsMacOS(); + } + + @override + Future getPlatformName() { + return api.getPlatformName(); + } +} diff --git a/plugins/toaster_utils/toaster_utils_macos/macos/toaster_utils_macos.podspec b/plugins/toaster_utils/toaster_utils_macos/macos/toaster_utils_macos.podspec new file mode 100644 index 0000000..db22bb9 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_macos/macos/toaster_utils_macos.podspec @@ -0,0 +1,21 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# +Pod::Spec.new do |s| + s.name = 'toaster_utils_macos' + s.version = '0.0.1' + s.summary = 'A macOS implementation of the toaster_utils plugin.' + s.description = <<-DESC + A macOS implementation of the toaster_utils plugin. + DESC + s.homepage = 'http://example.com' + s.license = { :type => 'BSD', :file => '../LICENSE' } + s.author = { 'Org Mars3142' => 'email@example.com' } + s.source = { :path => '.' } + s.source_files = 'toaster_utils_macos/Sources/**/*.swift' + s.dependency 'FlutterMacOS' + s.platform = :osx + s.osx.deployment_target = '10.15' + s.swift_version = '6.1' +end + diff --git a/plugins/toaster_utils/toaster_utils_macos/macos/toaster_utils_macos/Package.swift b/plugins/toaster_utils/toaster_utils_macos/macos/toaster_utils_macos/Package.swift new file mode 100644 index 0000000..9b5fd73 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_macos/macos/toaster_utils_macos/Package.swift @@ -0,0 +1,33 @@ +// swift-tools-version: 6.1 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "toaster_utils_macos", + platforms: [ + .macOS("10.15") + ], + products: [ + .library(name: "toaster-utils-macos", targets: ["toaster_utils_macos"]) + ], + dependencies: [], + targets: [ + .target( + name: "toaster_utils_macos", + dependencies: [], + resources: [ + // TODO: If your plugin requires a privacy manifest + // (e.g. if it uses any required reason APIs), update the PrivacyInfo.xcprivacy file + // to describe your plugin's privacy impact, and then uncomment this line. + // For more information, see: + // https://developer.apple.com/documentation/bundleresources/privacy_manifest_files + // .process("PrivacyInfo.xcprivacy"), + + // TODO: If you have other resources that need to be bundled with your plugin, refer to + // the following instructions to add them: + // https://developer.apple.com/documentation/xcode/bundling-resources-with-a-swift-package + ] + ) + ] +) \ No newline at end of file diff --git a/plugins/toaster_utils/toaster_utils_macos/macos/toaster_utils_macos/Sources/toaster_utils_macos/Messages.g.swift b/plugins/toaster_utils/toaster_utils_macos/macos/toaster_utils_macos/Sources/toaster_utils_macos/Messages.g.swift new file mode 100644 index 0000000..d8d079b --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_macos/macos/toaster_utils_macos/Sources/toaster_utils_macos/Messages.g.swift @@ -0,0 +1,117 @@ +// Copyright (c) 2026, Org mars3142 +// Autogenerated from Pigeon (v26.3.4), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +import Foundation + +#if os(iOS) + import Flutter +#elseif os(macOS) + import FlutterMacOS +#else + #error("Unsupported platform.") +#endif + +/// Error class for passing custom error details to Dart side. +final class PigeonError: Error { + let code: String + let message: String? + let details: Sendable? + + init(code: String, message: String?, details: Sendable?) { + self.code = code + self.message = message + self.details = details + } + + var localizedDescription: String { + return + "PigeonError(code: \(code), message: \(message ?? ""), details: \(details ?? "")" + } +} + +private func wrapResult(_ result: Any?) -> [Any?] { + return [result] +} + +private func wrapError(_ error: Any) -> [Any?] { + if let pigeonError = error as? PigeonError { + return [ + pigeonError.code, + pigeonError.message, + pigeonError.details, + ] + } + if let flutterError = error as? FlutterError { + return [ + flutterError.code, + flutterError.message, + flutterError.details, + ] + } + return [ + "\(error)", + "\(Swift.type(of: error))", + "Stacktrace: \(Thread.callStackSymbols)", + ] +} + +private func isNullish(_ value: Any?) -> Bool { + return value is NSNull || value == nil +} + +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? +} + + +private class MessagesPigeonCodecReader: FlutterStandardReader { +} + +private class MessagesPigeonCodecWriter: FlutterStandardWriter { +} + +private class MessagesPigeonCodecReaderWriter: FlutterStandardReaderWriter { + override func reader(with data: Data) -> FlutterStandardReader { + return MessagesPigeonCodecReader(data: data) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return MessagesPigeonCodecWriter(data: data) + } +} + +class MessagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable { + static let shared = MessagesPigeonCodec(readerWriter: MessagesPigeonCodecReaderWriter()) +} + + +/// Generated protocol from Pigeon that represents a handler of messages from Flutter. +protocol ToasterUtilsApi { + func getPlatformName(completion: @escaping (Result) -> Void) +} + +/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. +class ToasterUtilsApiSetup { + static var codec: FlutterStandardMessageCodec { MessagesPigeonCodec.shared } + /// Sets up an instance of `ToasterUtilsApi` to handle messages through the `binaryMessenger`. + static func setUp(binaryMessenger: FlutterBinaryMessenger, api: ToasterUtilsApi?, messageChannelSuffix: String = "") { + let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" + let getPlatformNameChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getPlatformName\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getPlatformNameChannel.setMessageHandler { _, reply in + api.getPlatformName { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + getPlatformNameChannel.setMessageHandler(nil) + } + } +} diff --git a/plugins/toaster_utils/toaster_utils_macos/macos/toaster_utils_macos/Sources/toaster_utils_macos/ToasterUtilsPlugin.swift b/plugins/toaster_utils/toaster_utils_macos/macos/toaster_utils_macos/Sources/toaster_utils_macos/ToasterUtilsPlugin.swift new file mode 100644 index 0000000..c398359 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_macos/macos/toaster_utils_macos/Sources/toaster_utils_macos/ToasterUtilsPlugin.swift @@ -0,0 +1,15 @@ +import FlutterMacOS +import Foundation + +public class ToasterUtilsPlugin: NSObject, FlutterPlugin, ToasterUtilsApi { + public static func register(with registrar: FlutterPluginRegistrar) { + let binaryMessenger = registrar.messenger + let instance = ToasterUtilsPlugin() + ToasterUtilsApiSetup.setUp(binaryMessenger: binaryMessenger, api: instance) + registrar.publish(instance) + } + + func getPlatformName(completion: @escaping (Result) -> Void) { + completion(.success("macOS")) + } +} diff --git a/plugins/toaster_utils/toaster_utils_macos/pigeons/copyright.txt b/plugins/toaster_utils/toaster_utils_macos/pigeons/copyright.txt new file mode 100644 index 0000000..7a8c0eb --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_macos/pigeons/copyright.txt @@ -0,0 +1 @@ +Copyright (c) 2026, Org mars3142 diff --git a/plugins/toaster_utils/toaster_utils_macos/pigeons/messages.dart b/plugins/toaster_utils/toaster_utils_macos/pigeons/messages.dart new file mode 100644 index 0000000..c7ee93a --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_macos/pigeons/messages.dart @@ -0,0 +1,19 @@ +// ToasterUtilsApi must be abstract. +// ignore_for_file: one_member_abstracts + +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon( + PigeonOptions( + dartOut: 'lib/src/messages.g.dart', + dartPackageName: 'toaster_utils', + swiftOut: 'macos/toaster_utils_macos/Sources/toaster_utils_macos/Messages.g.swift', + swiftOptions: SwiftOptions(), + copyrightHeader: 'pigeons/copyright.txt', + ), +) +@HostApi() +abstract class ToasterUtilsApi { + @async + String? getPlatformName(); +} diff --git a/plugins/toaster_utils/toaster_utils_macos/pubspec.yaml b/plugins/toaster_utils/toaster_utils_macos/pubspec.yaml new file mode 100644 index 0000000..b1f8345 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_macos/pubspec.yaml @@ -0,0 +1,30 @@ +name: toaster_utils_macos +description: MacOS implementation of the toaster_utils plugin +version: 0.1.0+1 +publish_to: none + +environment: + sdk: ^3.11.0 + +flutter: + plugin: + implements: toaster_utils + platforms: + macos: + pluginClass: ToasterUtilsPlugin + dartPluginClass: ToasterUtilsMacOS + +dependencies: + flutter: + sdk: flutter + toaster_utils_platform_interface: + path: ../toaster_utils_platform_interface + +dev_dependencies: + flutter_test: + sdk: flutter + mocktail: ^1.0.4 + pigeon: ^26.0.2 + very_good_analysis: ^10.2.0 + +resolution: workspace diff --git a/plugins/toaster_utils/toaster_utils_macos/test/toaster_utils_macos_test.dart b/plugins/toaster_utils/toaster_utils_macos/test/toaster_utils_macos_test.dart new file mode 100644 index 0000000..ec344b4 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_macos/test/toaster_utils_macos_test.dart @@ -0,0 +1,42 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:toaster_utils_macos/src/messages.g.dart'; +import 'package:toaster_utils_macos/toaster_utils_macos.dart'; +import 'package:toaster_utils_platform_interface/toaster_utils_platform_interface.dart'; + +class _MockToasterUtilsApi extends Mock + implements ToasterUtilsApi {} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group(ToasterUtilsMacOS, () { + const kPlatformName = 'MacOS'; + late ToasterUtilsMacOS toasterUtils; + late ToasterUtilsApi api; + + setUp(() { + api = _MockToasterUtilsApi(); + toasterUtils = ToasterUtilsMacOS(api: api); + }); + + test('can be registered', () { + ToasterUtilsMacOS.registerWith(); + expect( + ToasterUtilsPlatform.instance, + isA(), + ); + }); + + test('getPlatformName returns correct name', () async { + when(api.getPlatformName).thenAnswer((_) async => kPlatformName); + + await expectLater( + toasterUtils.getPlatformName(), + completion(equals(kPlatformName)), + ); + + verify(api.getPlatformName).called(1); + }); + }); +} diff --git a/plugins/toaster_utils/toaster_utils_platform_interface/README.md b/plugins/toaster_utils/toaster_utils_platform_interface/README.md new file mode 100644 index 0000000..ed4b938 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_platform_interface/README.md @@ -0,0 +1,14 @@ +# toaster_utils_platform_interface + +[![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] + +A common platform interface for the `toaster_utils` plugin. + +This interface allows platform-specific implementations of the `toaster_utils` plugin, as well as the plugin itself, to ensure they are supporting the same interface. + +# Usage + +To implement a new platform-specific implementation of `toaster_utils`, extend `ToasterUtilsPlatform` with an implementation that performs the platform-specific behavior. + +[very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg +[very_good_analysis_link]: https://pub.dev/packages/very_good_analysis \ No newline at end of file diff --git a/plugins/toaster_utils/toaster_utils_platform_interface/analysis_options.yaml b/plugins/toaster_utils/toaster_utils_platform_interface/analysis_options.yaml new file mode 100644 index 0000000..9df80aa --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_platform_interface/analysis_options.yaml @@ -0,0 +1 @@ +include: package:very_good_analysis/analysis_options.yaml diff --git a/plugins/toaster_utils/toaster_utils_platform_interface/lib/src/method_channel_toaster_utils.dart b/plugins/toaster_utils/toaster_utils_platform_interface/lib/src/method_channel_toaster_utils.dart new file mode 100644 index 0000000..f5292bf --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_platform_interface/lib/src/method_channel_toaster_utils.dart @@ -0,0 +1,17 @@ +import 'package:flutter/foundation.dart' show visibleForTesting; +import 'package:flutter/services.dart'; +import 'package:toaster_utils_platform_interface/toaster_utils_platform_interface.dart'; + +/// An implementation of [ToasterUtilsPlatform] +/// that uses method channels. +class MethodChannelToasterUtils + extends ToasterUtilsPlatform { + /// The method channel used to interact with the native platform. + @visibleForTesting + final methodChannel = const MethodChannel('toaster_utils'); + + @override + Future getPlatformName() { + return methodChannel.invokeMethod('getPlatformName'); + } +} diff --git a/plugins/toaster_utils/toaster_utils_platform_interface/lib/toaster_utils_platform_interface.dart b/plugins/toaster_utils/toaster_utils_platform_interface/lib/toaster_utils_platform_interface.dart new file mode 100644 index 0000000..9e6365c --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_platform_interface/lib/toaster_utils_platform_interface.dart @@ -0,0 +1,40 @@ +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import 'package:toaster_utils_platform_interface/src/method_channel_toaster_utils.dart'; + +/// {@template toaster_utils_platform} +/// The interface that implementations of +/// toaster_utils must implement. +/// +/// Platform implementations should extend this class +/// rather than implement it as `ToasterUtils`. +/// +/// Extending this class (using `extends`) ensures that the subclass will get +/// the default implementation, while platform implementations that `implements` +/// this interface will be broken by newly added +/// [ToasterUtilsPlatform] methods. +/// {@endtemplate} +abstract class ToasterUtilsPlatform extends PlatformInterface { + /// {@macro toaster_utils_platform} + ToasterUtilsPlatform() : super(token: _token); + + static final Object _token = Object(); + + static ToasterUtilsPlatform _instance = + MethodChannelToasterUtils(); + + /// The default instance of [ToasterUtilsPlatform] to use. + /// + /// Defaults to [MethodChannelToasterUtils]. + static ToasterUtilsPlatform get instance => _instance; + + /// Platform-specific plugins should set this with their own platform-specific + /// class that extends [ToasterUtilsPlatform] + /// when they register themselves. + static set instance(ToasterUtilsPlatform instance) { + PlatformInterface.verify(instance, _token); + _instance = instance; + } + + /// Return the current platform name. + Future getPlatformName(); +} diff --git a/plugins/toaster_utils/toaster_utils_platform_interface/pubspec.yaml b/plugins/toaster_utils/toaster_utils_platform_interface/pubspec.yaml new file mode 100644 index 0000000..d70aad1 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_platform_interface/pubspec.yaml @@ -0,0 +1,19 @@ +name: toaster_utils_platform_interface +description: A common platform interface for the toaster_utils plugin. +version: 0.1.0+1 +publish_to: none + +environment: + sdk: ^3.11.0 + +dependencies: + flutter: + sdk: flutter + plugin_platform_interface: ^2.1.8 + +dev_dependencies: + flutter_test: + sdk: flutter + very_good_analysis: ^10.2.0 + +resolution: workspace diff --git a/plugins/toaster_utils/toaster_utils_platform_interface/test/src/method_channel_toaster_utils_test.dart b/plugins/toaster_utils/toaster_utils_platform_interface/test/src/method_channel_toaster_utils_test.dart new file mode 100644 index 0000000..8524be4 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_platform_interface/test/src/method_channel_toaster_utils_test.dart @@ -0,0 +1,43 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:toaster_utils_platform_interface/src/method_channel_toaster_utils.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + const kPlatformName = 'platformName'; + + group('$MethodChannelToasterUtils', () { + late MethodChannelToasterUtils + methodChannelToasterUtils; + final log = []; + + setUp(() { + methodChannelToasterUtils = MethodChannelToasterUtils(); + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler( + methodChannelToasterUtils.methodChannel, + (methodCall) async { + log.add(methodCall); + switch (methodCall.method) { + case 'getPlatformName': + return kPlatformName; + default: + return null; + } + }, + ); + }); + + tearDown(log.clear); + + test('getPlatformName', () async { + final platformName = await methodChannelToasterUtils + .getPlatformName(); + expect( + log, + [isMethodCall('getPlatformName', arguments: null)], + ); + expect(platformName, equals(kPlatformName)); + }); + }); +} diff --git a/plugins/toaster_utils/toaster_utils_platform_interface/test/toaster_utils_platform_interface_test.dart b/plugins/toaster_utils/toaster_utils_platform_interface/test/toaster_utils_platform_interface_test.dart new file mode 100644 index 0000000..e727790 --- /dev/null +++ b/plugins/toaster_utils/toaster_utils_platform_interface/test/toaster_utils_platform_interface_test.dart @@ -0,0 +1,33 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:toaster_utils_platform_interface/toaster_utils_platform_interface.dart'; + +class ToasterUtilsMock + extends ToasterUtilsPlatform { + static const mockPlatformName = 'Mock'; + + @override + Future getPlatformName() async => mockPlatformName; +} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + group('ToasterUtilsPlatformInterface', () { + late ToasterUtilsPlatform + toasterUtilsPlatform; + + setUp(() { + toasterUtilsPlatform = ToasterUtilsMock(); + ToasterUtilsPlatform.instance = + toasterUtilsPlatform; + }); + + group('getPlatformName', () { + test('returns correct name', () async { + expect( + await ToasterUtilsPlatform.instance.getPlatformName(), + equals(ToasterUtilsMock.mockPlatformName), + ); + }); + }); + }); +} diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..d617b81 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,30 @@ +name: toaster_workspace + +environment: + sdk: ">=3.11.4 <4.0.0" + +dev_dependencies: + melos: ^7.5.1 + +workspace: + - apps + - packages/toaster_ui + - plugins/toaster_utils/* + +melos: + scripts: + get: + run: melos exec -c 1 -- flutter pub get + description: Run flutter pub get in all packages + + generate: + run: melos exec -c 1 --depends-on build_runner -- dart run build_runner build + description: Run build_runner in all packages with build_runner dependency + + pigeon: + run: melos exec -c 1 --depends-on pigeon -- dart run pigeon --input pigeons/messages.dart + description: Run pigeon code generation in all packages with pigeon dependency + + test: + run: melos exec -c 1 --dir-exists=test -- flutter test + description: Run tests in all packages \ No newline at end of file