├── .gitignore ├── .metadata ├── .vscode └── launch.json ├── README.md ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── devs │ │ │ │ └── help │ │ │ │ └── devs │ │ │ │ └── donation_tracker │ │ │ │ └── MainActivity.java │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── devs │ │ │ │ └── help │ │ │ │ └── devs │ │ │ │ └── donation_tracker │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-v21 │ │ │ └── launch_background.xml │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-night │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── assets └── images │ ├── devshelpdevs-logo.svg │ └── logo.png ├── buildweb.bat ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── Runner │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-App-1024x1024@1x.png │ │ ├── Icon-App-20x20@1x.png │ │ ├── Icon-App-20x20@2x.png │ │ ├── Icon-App-20x20@3x.png │ │ ├── Icon-App-29x29@1x.png │ │ ├── Icon-App-29x29@2x.png │ │ ├── Icon-App-29x29@3x.png │ │ ├── Icon-App-40x40@1x.png │ │ ├── Icon-App-40x40@2x.png │ │ ├── Icon-App-40x40@3x.png │ │ ├── Icon-App-60x60@2x.png │ │ ├── Icon-App-60x60@3x.png │ │ ├── Icon-App-76x76@1x.png │ │ ├── Icon-App-76x76@2x.png │ │ └── Icon-App-83.5x83.5@2x.png │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ ├── LaunchImage.png │ │ ├── LaunchImage@2x.png │ │ ├── LaunchImage@3x.png │ │ └── README.md │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── Runner-Bridging-Header.h │ └── main.m ├── lib ├── _managers │ ├── authentication_manager.dart │ ├── donation_manager.dart │ └── donation_manager_logged_in.dart ├── _services │ └── nhost_service.dart ├── constants.dart ├── graphQlRequests.dart ├── main.dart ├── models │ ├── donation.dart │ └── usage.dart ├── presentation │ ├── button.dart │ ├── dialogs.dart │ ├── donations.dart │ ├── edit_donation_dlg.dart │ ├── edit_usage_dlg.dart │ ├── select_image_dlg.dart │ └── usage.dart └── utils.dart ├── macos ├── .gitignore ├── Flutter │ ├── Flutter-Debug.xcconfig │ ├── Flutter-Release.xcconfig │ └── GeneratedPluginRegistrant.swift ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── app_icon_1024.png │ │ ├── app_icon_128.png │ │ ├── app_icon_16.png │ │ ├── app_icon_256.png │ │ ├── app_icon_32.png │ │ ├── app_icon_512.png │ │ └── app_icon_64.png │ ├── Base.lproj │ └── MainMenu.xib │ ├── Configs │ ├── AppInfo.xcconfig │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── Warnings.xcconfig │ ├── DebugProfile.entitlements │ ├── Info.plist │ ├── MainFlutterWindow.swift │ └── Release.entitlements ├── pubspec.lock ├── pubspec.yaml ├── test ├── graphQL_test.dart ├── storage_test.dart └── widget_test.dart ├── web ├── _redirects ├── favicon.ico ├── favicon.png ├── icons │ ├── Icon-192.png │ └── Icon-512.png ├── index.html ├── loader.css └── manifest.json └── windows ├── .gitignore ├── CMakeLists.txt ├── flutter ├── CMakeLists.txt ├── ephemeral │ ├── cpp_client_wrapper │ │ ├── README │ │ ├── binary_messenger_impl.h │ │ ├── byte_buffer_streams.h │ │ ├── byte_stream_wrappers.h │ │ ├── core_implementations.cc │ │ ├── engine_method_result.cc │ │ ├── flutter_engine.cc │ │ ├── flutter_view_controller.cc │ │ ├── include │ │ │ └── flutter │ │ │ │ ├── basic_message_channel.h │ │ │ │ ├── binary_messenger.h │ │ │ │ ├── byte_streams.h │ │ │ │ ├── dart_project.h │ │ │ │ ├── encodable_value.h │ │ │ │ ├── engine_method_result.h │ │ │ │ ├── event_channel.h │ │ │ │ ├── event_sink.h │ │ │ │ ├── event_stream_handler.h │ │ │ │ ├── event_stream_handler_functions.h │ │ │ │ ├── flutter_engine.h │ │ │ │ ├── flutter_view.h │ │ │ │ ├── flutter_view_controller.h │ │ │ │ ├── json_message_codec.h │ │ │ │ ├── json_method_codec.h │ │ │ │ ├── json_type.h │ │ │ │ ├── message_codec.h │ │ │ │ ├── method_call.h │ │ │ │ ├── method_channel.h │ │ │ │ ├── method_codec.h │ │ │ │ ├── method_result.h │ │ │ │ ├── method_result_functions.h │ │ │ │ ├── plugin_registrar.h │ │ │ │ ├── plugin_registrar_windows.h │ │ │ │ ├── plugin_registry.h │ │ │ │ ├── standard_codec_serializer.h │ │ │ │ ├── standard_message_codec.h │ │ │ │ ├── standard_method_codec.h │ │ │ │ └── texture_registrar.h │ │ ├── json_message_codec.cc │ │ ├── json_method_codec.cc │ │ ├── plugin_registrar.cc │ │ ├── standard_codec.cc │ │ ├── standard_codec_serializer.h │ │ └── texture_registrar_impl.h │ ├── flutter_export.h │ ├── flutter_messenger.h │ ├── flutter_plugin_registrar.h │ ├── flutter_texture_registrar.h │ ├── flutter_windows.dll │ ├── flutter_windows.dll.lib │ ├── flutter_windows.h │ └── icudtl.dat └── generated_plugins.cmake └── runner ├── CMakeLists.txt ├── Runner.rc ├── flutter_window.cpp ├── flutter_window.h ├── main.cpp ├── resource.h ├── resources └── app_icon.ico ├── run_loop.cpp ├── run_loop.h ├── runner.exe.manifest ├── utils.cpp ├── utils.h ├── win32_window.cpp └── win32_window.h /.gitignore: -------------------------------------------------------------------------------- 1 | # File used by https://detective.dev/, containing the VM service socket URL of 2 | # the currently running app 3 | detective_connect.txt 4 | 5 | # Miscellaneous 6 | *.class 7 | *.log 8 | *.pyc 9 | *.swp 10 | .DS_Store 11 | .atom/ 12 | .buildlog/ 13 | .history 14 | .svn/ 15 | 16 | # IntelliJ related 17 | *.iml 18 | *.ipr 19 | *.iws 20 | .idea/ 21 | 22 | # The .vscode folder contains launch configuration and tasks you configure in 23 | # VS Code which you may wish to be included in version control, so this line 24 | # is commented out by default. 25 | #.vscode/ 26 | 27 | # Flutter/Dart/Pub related 28 | **/doc/api/ 29 | **/ios/Flutter/.last_build_id 30 | .dart_tool/ 31 | .flutter-plugins 32 | .flutter-plugins-dependencies 33 | .packages 34 | .pub-cache/ 35 | .pub/ 36 | /build/ 37 | 38 | # Web related 39 | lib/generated_plugin_registrant.dart 40 | 41 | # Symbolication related 42 | app.*.symbols 43 | 44 | # Obfuscation related 45 | app.*.map.json 46 | 47 | # Android Studio will place build artifacts here 48 | /android/app/debug 49 | /android/app/profile 50 | /android/app/release 51 | *.pdb 52 | windows/flutter/generated_plugin_registrant.h 53 | windows/flutter/generated_plugin_registrant.cc 54 | *.exp 55 | windows/flutter/ephemeral/generated_config.cmake 56 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 4d7946a68d26794349189cf21b3f68cc6fe61dcb 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "donation_tracker_public", 9 | "request": "launch", 10 | "type": "dart", 11 | "args": [ 12 | "--dart-define", 13 | "SERVER=3fad0791.nhost.app", 14 | ] 15 | }, 16 | { 17 | "name": "donation_tracker_staging_write_access", 18 | "request": "launch", 19 | "type": "dart", 20 | "args": [ 21 | "--dart-define", 22 | "SERVER=63b34375.nhost.app", 23 | "--vmservice-out-file=detective_connect.txt" 24 | ] 25 | }, 26 | { 27 | "name": "run tests on staging", 28 | "type": "dart", 29 | "request": "launch", 30 | "codeLens": { 31 | // Types of CodeLens to inject 32 | "for": [ 33 | "run-test", 34 | "run-test-file", 35 | "debug-test", 36 | "debug-test-file" 37 | ], 38 | // Restrict to certain folders 39 | "path": "test", 40 | // Text for CodeLens link (${debugType} will be replaced with "run" or "debug") 41 | "title": "${debugType} (onStaging)" 42 | }, 43 | "args": [ 44 | "--dart-define", 45 | "SERVER=63b34375.nhost.app", 46 | ] 47 | } 48 | ] 49 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is the repository for the DevsHelpDevs Donation Tracker Flutter Web app https://helpdevs-tracker.netlify.app 2 | # donation_tracker 3 | 4 | Because I get regularly requests for help for repairs or updates and I don't want to wait to have the DevsHelpDevs platform finished, Jimmy and I developed this flutter web app to allow me to track and show all donations usages and waiting people. 5 | Besides that it helps me to keep better track of and outgoing money, it will also act as a proof of concept for the whole platform. 6 | 7 | As it turned out that I will need to use this app more than originally thought and to be able to make it possible that other developers can easily contribute, the app can be configured when building or running a passing and a environment variable to define the used database server end up in secrets. 8 | 9 | ## Possible configurations 10 | 11 | To allow adding editing features in a safe way I set up a separate staging backend on Nhost which can be used by everyone for developing. 12 | 13 | To select the staging backend you have to pass in the server it should use: 14 | 15 | ``` 16 | --dart-define SERVER=63b34375.nhost.app 17 | ``` 18 | 19 | To be able to make mutation to data you have to log-in. you do that be double clicking on the DHD logo. If you selected the staging configuration you don't have to provide a password. 20 | 21 | For VS code I included 2 different run configurations to switch between read only production database and write access staging server. 22 | If you don't provide any environment variable the app defaults to read only production server. 23 | If you are using android studio you will have to find out how to class in built environment variables yourself 24 | 25 | The `NHostService` class has a property `hasWriteAccess` that can be used by the app to switch between readonly and editing mode. 26 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 30 29 | 30 | defaultConfig { 31 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 32 | applicationId "com.devs.help.devs.donation_tracker" 33 | minSdkVersion 16 34 | targetSdkVersion 30 35 | versionCode flutterVersionCode.toInteger() 36 | versionName flutterVersionName 37 | } 38 | 39 | buildTypes { 40 | release { 41 | // TODO: Add your own signing config for the release build. 42 | // Signing with the debug keys for now, so `flutter run --release` works. 43 | signingConfig signingConfigs.debug 44 | } 45 | } 46 | } 47 | 48 | flutter { 49 | source '../..' 50 | } 51 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 13 | 17 | 21 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/devs/help/devs/donation_tracker/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.devs.help.devs.donation_tracker; 2 | 3 | import io.flutter.embedding.android.FlutterActivity; 4 | 5 | public class MainActivity extends FlutterActivity { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/devs/help/devs/donation_tracker/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.devs.help.devs.donation_tracker 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:4.1.0' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/assets/images/logo.png -------------------------------------------------------------------------------- /buildweb.bat: -------------------------------------------------------------------------------- 1 | flutter build web --release --dart-define SERVER=3fad0791.nhost.app --web-renderer html -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 32 | end 33 | 34 | post_install do |installer| 35 | installer.pods_project.targets.each do |target| 36 | flutter_additional_ios_build_settings(target) 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - connectivity (0.0.1): 3 | - Flutter 4 | - Reachability 5 | - Flutter (1.0.0) 6 | - path_provider (0.0.1): 7 | - Flutter 8 | - Reachability (3.2) 9 | 10 | DEPENDENCIES: 11 | - connectivity (from `.symlinks/plugins/connectivity/ios`) 12 | - Flutter (from `Flutter`) 13 | - path_provider (from `.symlinks/plugins/path_provider/ios`) 14 | 15 | SPEC REPOS: 16 | trunk: 17 | - Reachability 18 | 19 | EXTERNAL SOURCES: 20 | connectivity: 21 | :path: ".symlinks/plugins/connectivity/ios" 22 | Flutter: 23 | :path: Flutter 24 | path_provider: 25 | :path: ".symlinks/plugins/path_provider/ios" 26 | 27 | SPEC CHECKSUMS: 28 | connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467 29 | Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c 30 | path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c 31 | Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 32 | 33 | PODFILE CHECKSUM: 8e679eca47255a8ca8067c4c67aab20e64cb974d 34 | 35 | COCOAPODS: 1.10.1 36 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #import "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | 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. -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | donation_tracker 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/_managers/authentication_manager.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:donation_tracker/_managers/donation_manager.dart'; 4 | import 'package:donation_tracker/_managers/donation_manager_logged_in.dart'; 5 | import 'package:donation_tracker/_services/nhost_service.dart'; 6 | import 'package:flutter_command/flutter_command.dart'; 7 | import 'package:functional_listener/functional_listener.dart'; 8 | import 'package:get_it/get_it.dart'; 9 | 10 | class LoginCredentials { 11 | final String name; 12 | final String pwd; 13 | 14 | LoginCredentials(this.name, this.pwd); 15 | } 16 | 17 | class AuthenticationManager { 18 | bool get isLoggedIn => GetIt.I().hasWriteAccess; 19 | 20 | late final Command loginCommand; 21 | late final Command logoutCommand; 22 | 23 | AuthenticationManager() { 24 | loginCommand = Command.createAsyncNoResult( 25 | (x) async => await loginUser(x.name, x.pwd), 26 | ); 27 | logoutCommand = Command.createAsyncNoParamNoResult( 28 | () async => await logout(), 29 | ); 30 | 31 | loginCommand.thrownExceptions.listen((ex, _) => print(ex.toString())); 32 | } 33 | 34 | Future loginUser(String userName, String pwd) async { 35 | if (isLoggedIn) return; 36 | if (await GetIt.I().loginUser(userName, pwd)) { 37 | GetIt.I.pushNewScope( 38 | scopeName: 'logged In', 39 | init: (getIt) { 40 | getIt.registerSingleton(NhostService(true)); 41 | getIt.registerSingleton(DonationManagerLoggedIn()); 42 | }); 43 | } 44 | } 45 | 46 | Future logout() async { 47 | await GetIt.I.popScope(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/_managers/donation_manager.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:donation_tracker/_services/nhost_service.dart'; 4 | import 'package:donation_tracker/models/donation.dart'; 5 | import 'package:donation_tracker/models/usage.dart'; 6 | import 'package:flutter/foundation.dart'; 7 | import 'package:flutter_command/flutter_command.dart'; 8 | import 'package:get_it/get_it.dart'; 9 | 10 | class DonationManager implements ShadowChangeHandlers { 11 | final ValueListenable loading = ValueNotifier(false); 12 | final error = ValueNotifier(null); 13 | final totalDonated = ValueNotifier(0); 14 | final totalUsed = ValueNotifier(0); 15 | final totalWaiting = ValueNotifier(0); 16 | 17 | final donationUpdates = ValueNotifier([]); 18 | final usageUpdates = ValueNotifier>([]); 19 | final waitingUpdates = ValueNotifier>([]); 20 | 21 | Command? upsertDonation; 22 | Command? deleteDonation; 23 | Command? upsertUsage; 24 | Command? deleteUsage; 25 | 26 | late StreamSubscription donationSubscription; 27 | late StreamSubscription usageSubscription; 28 | late StreamSubscription errorSubscription; 29 | 30 | DonationManager() { 31 | startDatabaseListeners(); 32 | } 33 | @override 34 | void onGetShadowed(Object shadowing) { 35 | stopListeners(); 36 | } 37 | 38 | @override 39 | void onLeaveShadow(Object shadowing) { 40 | startDatabaseListeners(); 41 | } 42 | 43 | void startDatabaseListeners() { 44 | final nhostService = GetIt.I(); 45 | 46 | donationSubscription = nhostService.donationTableUpdates.listen((list) { 47 | totalDonated.value = list.fold( 48 | 0, (previousValue, element) => previousValue + element.amount); 49 | 50 | donationUpdates.value = list; 51 | }); 52 | 53 | usageSubscription = nhostService.usageTableUpdates.listen((list) { 54 | /// We are using the same table for already used donations and for causes waiting 55 | final used = list.where((x) => !x.isWaitingCause); 56 | final waiting = list.where((x) => x.isWaitingCause); 57 | 58 | totalUsed.value = used.fold( 59 | 0, (previousValue, element) => previousValue + element.amount); 60 | totalWaiting.value = waiting.fold( 61 | 0, (previousValue, element) => previousValue + element.amount); 62 | 63 | usageUpdates.value = used.toList(); 64 | waitingUpdates.value = waiting.toList(); 65 | }); 66 | 67 | errorSubscription = nhostService.errorUpdates.listen((event) { 68 | /// This might be a bit brutal in case there is an error but I don't expect many to happen :-) 69 | error.value = event.toString(); 70 | }); 71 | } 72 | 73 | Future stopListeners() async { 74 | await donationSubscription.cancel(); 75 | await usageSubscription.cancel(); 76 | await errorSubscription.cancel(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /lib/_managers/donation_manager_logged_in.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:donation_tracker/_managers/donation_manager.dart'; 4 | import 'package:donation_tracker/_services/nhost_service.dart'; 5 | import 'package:flutter/foundation.dart'; 6 | import 'package:flutter_command/flutter_command.dart'; 7 | import 'package:functional_listener/functional_listener.dart'; 8 | import 'package:get_it/get_it.dart'; 9 | 10 | class DonationManagerLoggedIn extends DonationManager implements Disposable { 11 | @override 12 | late final ValueListenable loading; 13 | 14 | DonationManagerLoggedIn() { 15 | upsertDonation = Command.createAsync((donation) async { 16 | if (donation.id != null) { 17 | await GetIt.I().updateDonation(donation); 18 | } else { 19 | await GetIt.I().addDonation(donation); 20 | } 21 | return true; 22 | }, false); 23 | 24 | deleteDonation = Command.createAsync((donation) async { 25 | await GetIt.I().deleteDonation(donation); 26 | await Future.delayed(const Duration(seconds: 2)); 27 | return true; 28 | }, false); 29 | 30 | upsertUsage = Command.createAsync((usage) async { 31 | if (usage.id != null) { 32 | await GetIt.I().updateUsage(usage); 33 | } else { 34 | await GetIt.I().addUsage(usage); 35 | } 36 | return true; 37 | }, false); 38 | 39 | deleteUsage = Command.createAsync((usage) async { 40 | await GetIt.I().deleteUsage(usage); 41 | await Future.delayed(const Duration(seconds: 2)); 42 | return true; 43 | }, false); 44 | 45 | loading = upsertDonation!.isExecuting.mergeWith([ 46 | deleteDonation!.isExecuting, 47 | upsertUsage!.isExecuting, 48 | deleteUsage!.isExecuting 49 | ]); 50 | deleteUsage!.thrownExceptions.listen((error, _) { 51 | print(error.toString()); 52 | }); 53 | } 54 | @override 55 | FutureOr onDispose() { 56 | stopListeners(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /lib/constants.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | Color kColorFromHex(String color) { 4 | final hexColorTrim = color 5 | .toUpperCase() 6 | .replaceAll('#', '') 7 | .replaceAll('0X', '') 8 | .padLeft(8, 'F'); 9 | return Color(int.parse(hexColorTrim, radix: 16)); 10 | } 11 | 12 | final tableDonations = 'temp_money_donations'; 13 | final tableUsages = 'temp_money_used_for'; 14 | final backgroundColor = kColorFromHex('#14142B'); 15 | final primaryColor = kColorFromHex('#115FA7'); 16 | 17 | const tableHeaderStyle = TextStyle(fontWeight: FontWeight.bold, fontSize: 16); 18 | 19 | const server = 20 | const String.fromEnvironment('SERVER', defaultValue: '3fad0791.nhost.app'); 21 | 22 | const isProduction = server == '3fad0791.nhost.app'; 23 | 24 | const hasuraSecret = const String.fromEnvironment('HASURA_SECRET'); 25 | const userID = const String.fromEnvironment('USER_ID'); 26 | const authPassword = const String.fromEnvironment('AUTH_PASSWORD'); 27 | 28 | const graphQlEndPoint = 'https://hasura-$server/v1/graphql'; 29 | 30 | const nhostBaseUrl = 'https://backend-$server'; 31 | 32 | String buildImageLink(String fileNamePath) => 33 | '$nhostBaseUrl/storage/o/public/$fileNamePath'; 34 | -------------------------------------------------------------------------------- /lib/models/donation.dart: -------------------------------------------------------------------------------- 1 | class Donation { 2 | const Donation({ 3 | this.id, 4 | this.name, 5 | this.hiddenName, 6 | required this.amount, 7 | required this.date, 8 | }); 9 | 10 | factory Donation.fromMap(Map data) { 11 | return Donation( 12 | id: data['id'], 13 | name: data['donator'], 14 | hiddenName: data['donator_hidden'], 15 | amount: data['value'], 16 | date: data['donation_date']); 17 | } 18 | 19 | final int? id; 20 | final String? name; 21 | final String? hiddenName; 22 | final int amount; 23 | final String date; 24 | 25 | Donation copyWith({ 26 | int? id, 27 | String? name, 28 | String? hiddenName, 29 | int? amount, 30 | String? date, 31 | }) => 32 | Donation( 33 | id: id ?? this.id, 34 | name: name ?? this.name, 35 | hiddenName: hiddenName ?? this.hiddenName, 36 | amount: amount ?? this.amount, 37 | date: date ?? this.date, 38 | ); 39 | 40 | @override 41 | String toString() { 42 | return 'Donator{id: $id, name: $name, amount: $amount, createdAt: $date}'; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/models/usage.dart: -------------------------------------------------------------------------------- 1 | import 'package:donation_tracker/constants.dart'; 2 | import 'package:donation_tracker/utils.dart'; 3 | 4 | ///We use the same table for already used money as well as for people waiting for help 5 | /// if [date] is null it means that this is a waiting entry 6 | class Usage { 7 | const Usage({ 8 | this.id, 9 | required this.whatFor, 10 | required this.amount, 11 | this.date, 12 | this.name, 13 | this.hiddenName, 14 | this.image, 15 | this.imageReceiver, 16 | }); 17 | 18 | factory Usage.fromMap(Map data) { 19 | return Usage( 20 | id: data['id'], 21 | whatFor: data['usage'], 22 | amount: data['value'], 23 | date: data['usage_date'], 24 | name: data['receivers_name'], 25 | hiddenName: data['receiver_hidden_name'], 26 | image: data['storage_image_name'], 27 | imageReceiver: data['storage_image_name_person']); 28 | } 29 | 30 | bool get isWaitingCause => date == null; 31 | 32 | final int? id; 33 | final String whatFor; 34 | final int amount; 35 | final String? date; 36 | final String? name; 37 | final String? hiddenName; 38 | final String? image; 39 | final String? imageReceiver; 40 | 41 | String? get imageLink => 42 | image == null ? null : '$nhostBaseUrl/storage/o/public/$image'; 43 | 44 | String? get imageReceiverLink => imageReceiver == null 45 | ? null 46 | : '$nhostBaseUrl/storage/o/public/$imageReceiver'; 47 | 48 | String get dateText { 49 | return date?.toDateTime().format() ?? 'missing'; 50 | } 51 | 52 | Usage copyWith({ 53 | int? id, 54 | String? whatFor, 55 | int? amount, 56 | String? date, 57 | String? name, 58 | String? hiddenName, 59 | String? image, 60 | String? imageReceiver, 61 | }) => 62 | Usage( 63 | id: id ?? this.id, 64 | whatFor: whatFor ?? this.whatFor, 65 | amount: amount ?? this.amount, 66 | date: date ?? this.date, 67 | name: name ?? this.name, 68 | hiddenName: hiddenName ?? this.hiddenName, 69 | image: image ?? this.image, 70 | imageReceiver: imageReceiver ?? this.imageReceiver, 71 | ); 72 | 73 | @override 74 | String toString() { 75 | return 'Usage{id: $id, whatFor: $whatFor, amount: $amount, createdAt: $date}'; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /lib/presentation/button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class Button extends StatelessWidget { 4 | final VoidCallback onPressed; 5 | final String text; 6 | const Button({Key? key, required this.onPressed, required this.text}) 7 | : super(key: key); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return TextButton( 12 | onPressed: onPressed, 13 | child: Padding( 14 | padding: const EdgeInsets.only(left: 8.0, top: 8, right: 8, bottom: 9), 15 | child: Text( 16 | text, 17 | style: Theme.of(context) 18 | .textTheme 19 | .headline5! 20 | .copyWith(color: Colors.white), 21 | ), 22 | ), 23 | style: OutlinedButton.styleFrom( 24 | backgroundColor: const Color(0xff115FA7), 25 | side: BorderSide(color: const Color(0xff115FA7), width: 3), 26 | shape: StadiumBorder(), 27 | ), 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/presentation/donations.dart: -------------------------------------------------------------------------------- 1 | import 'package:donation_tracker/_managers/donation_manager.dart'; 2 | import 'package:donation_tracker/_services/nhost_service.dart'; 3 | import 'package:donation_tracker/constants.dart'; 4 | import 'package:donation_tracker/presentation/dialogs.dart'; 5 | import 'package:donation_tracker/presentation/edit_donation_dlg.dart'; 6 | import 'package:donation_tracker/utils.dart'; 7 | import 'package:flutter/material.dart'; 8 | import 'package:get_it_mixin/get_it_mixin.dart'; 9 | 10 | class Donations extends StatelessWidget with GetItMixin { 11 | @override 12 | Widget build(BuildContext context) { 13 | final hasWriteAccess = get().hasWriteAccess; 14 | final donations = watchX((DonationManager m) => m.donationUpdates); 15 | return SingleChildScrollView( 16 | child: Column( 17 | crossAxisAlignment: CrossAxisAlignment.stretch, 18 | children: [ 19 | DataTable( 20 | rows: donations 21 | .map((data) { 22 | return DataRow(cells: [ 23 | DataCell(Text(data.name ?? 'anonymous')), 24 | DataCell(Text(data.date.toDateTime().format())), 25 | DataCell(Text(data.amount.toCurrency())), 26 | if (hasWriteAccess) 27 | DataCell( 28 | IconButton( 29 | onPressed: () async { 30 | await showAddEditDonationDlg(context, data); 31 | }, 32 | icon: Icon(Icons.edit), 33 | ), 34 | ), 35 | if (hasWriteAccess) 36 | DataCell(IconButton( 37 | onPressed: () async { 38 | final shouldDelete = await showQueryDialog( 39 | context, 40 | 'Warning!', 41 | 'Do you really want to delete this entry?'); 42 | if (shouldDelete) { 43 | get().deleteDonation!(data); 44 | } 45 | }, 46 | icon: Icon(Icons.delete))) 47 | ]); 48 | }) 49 | .cast() 50 | .toList(), 51 | columns: [ 52 | DataColumn( 53 | label: const Text('Name', style: tableHeaderStyle), 54 | ), 55 | DataColumn( 56 | label: const Text('Date', style: tableHeaderStyle), 57 | ), 58 | DataColumn( 59 | label: const Text('Amount', style: tableHeaderStyle), 60 | ), 61 | if (hasWriteAccess) 62 | DataColumn( 63 | label: const Text('Edit', style: tableHeaderStyle), 64 | ), 65 | if (hasWriteAccess) 66 | DataColumn( 67 | label: const Text('Delete', style: tableHeaderStyle), 68 | ), 69 | ], 70 | ), 71 | ], 72 | ), 73 | ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /lib/utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:intl/date_symbol_data_local.dart'; 2 | import 'package:intl/intl.dart'; 3 | 4 | final _numberFormat = NumberFormat('#,##0.00'); 5 | 6 | extension DateTimeExtension on DateTime { 7 | String format({String pattern = 'dd/MM/yyyy', String locale = 'fr_FR'}) { 8 | initializeDateFormatting(locale); 9 | return DateFormat(pattern, locale).format(this); 10 | } 11 | } 12 | 13 | extension ToDateExtension on String { 14 | DateTime toDateTime() { 15 | return DateFormat('yyyy-MM-dd\'T\'HH:mm:ssZ').parse(this); 16 | } 17 | } 18 | 19 | extension ToStringCurrency on num { 20 | String toCurrency() { 21 | var amount = this ~/ 100; 22 | return _numberFormat.format(amount) + '€'; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/xcuserdata/ 7 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import dropfiles_window 9 | import url_launcher_macos 10 | 11 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 12 | DropfilesWindowPlugin.register(with: registry.registrar(forPlugin: "DropfilesWindowPlugin")) 13 | UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) 14 | } 15 | -------------------------------------------------------------------------------- /macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.11' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def flutter_root 13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) 14 | unless File.exist?(generated_xcode_build_settings_path) 15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" 16 | end 17 | 18 | File.foreach(generated_xcode_build_settings_path) do |line| 19 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 20 | return matches[1].strip if matches 21 | end 22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" 23 | end 24 | 25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 26 | 27 | flutter_macos_podfile_setup 28 | 29 | target 'Runner' do 30 | use_frameworks! 31 | use_modular_headers! 32 | 33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) 34 | end 35 | 36 | post_install do |installer| 37 | installer.pods_project.targets.each do |target| 38 | flutter_additional_macos_build_settings(target) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /macos/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - dropfiles_window (0.0.1): 3 | - FlutterMacOS 4 | - FlutterMacOS (1.0.0) 5 | - url_launcher_macos (0.0.1): 6 | - FlutterMacOS 7 | 8 | DEPENDENCIES: 9 | - dropfiles_window (from `Flutter/ephemeral/.symlinks/plugins/dropfiles_window/macos`) 10 | - FlutterMacOS (from `Flutter/ephemeral`) 11 | - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) 12 | 13 | EXTERNAL SOURCES: 14 | dropfiles_window: 15 | :path: Flutter/ephemeral/.symlinks/plugins/dropfiles_window/macos 16 | FlutterMacOS: 17 | :path: Flutter/ephemeral 18 | url_launcher_macos: 19 | :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos 20 | 21 | SPEC CHECKSUMS: 22 | dropfiles_window: 830efdb761ce08d5da6c5930803431bc445d5881 23 | FlutterMacOS: 57701585bf7de1b3fc2bb61f6378d73bbdea8424 24 | url_launcher_macos: 45af3d61de06997666568a7149c1be98b41c95d4 25 | 26 | PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c 27 | 28 | COCOAPODS: 1.10.1 29 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 64 | 65 | 71 | 73 | 79 | 80 | 81 | 82 | 84 | 85 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = donation_tracker 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.devs.help.devs.donationTracker 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2021 com.devs.help.devs. All rights reserved. 15 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.client 10 | 11 | com.apple.security.network.server 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.network.client 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: donation_tracker 2 | description: DevsHelpDevs Donation Tracker 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: ">=2.12.0 <3.0.0" 22 | 23 | dependencies: 24 | intl: ^0.17.0 25 | cropper: ^0.5.2 26 | dropfiles_window: 27 | git: 28 | url: https://github.com/escamoteur/dropfiles_window 29 | ref: null-safety 30 | graphql: 5.0.0-nullsafety.1 31 | get_it: ^7.1.2 32 | file_selector: 33 | file_selector_windows: ^0.0.2 34 | flutter_command: any 35 | get_it_mixin: ^3.1.1 36 | image: 37 | url_launcher: 38 | rxdart: 39 | layout: 40 | functional_listener: ^2.0.2 41 | deep_pick: ^0.8.0 42 | flutter_svg: 43 | modal_bottom_sheet: ^2.0.0 44 | reactive_forms: 45 | routemaster: ^0.8.1 46 | flutter: 47 | sdk: flutter 48 | 49 | # The following adds the Cupertino Icons font to your application. 50 | # Use with the CupertinoIcons class for iOS style icons. 51 | cupertino_icons: ^1.0.2 52 | 53 | # Nhost-related 54 | nhost_sdk: 55 | nhost_graphql_adapter: 56 | 57 | dev_dependencies: 58 | test: 59 | flutter_test: 60 | sdk: flutter 61 | 62 | # For information on the generic Dart part of this file, see the 63 | # following page: https://dart.dev/tools/pub/pubspec 64 | 65 | # The following section is specific to Flutter. 66 | flutter: 67 | 68 | # The following line ensures that the Material Icons font is 69 | # included with your application, so that you can use the icons in 70 | # the material Icons class. 71 | uses-material-design: true 72 | 73 | # To add assets to your application, add an assets section, like this: 74 | assets: 75 | - assets/images/ 76 | 77 | # An image asset can refer to one or more resolution-specific "variants", see 78 | # https://flutter.dev/assets-and-images/#resolution-aware. 79 | 80 | # For details regarding adding assets from package dependencies, see 81 | # https://flutter.dev/assets-and-images/#from-packages 82 | 83 | # To add custom fonts to your application, add a fonts section here, 84 | # in this "flutter" section. Each entry in this list should have a 85 | # "family" key with the font family name, and a "fonts" key with a 86 | # list giving the asset and other descriptors for the font. For 87 | # example: 88 | # fonts: 89 | # - family: Schyler 90 | # fonts: 91 | # - asset: fonts/Schyler-Regular.ttf 92 | # - asset: fonts/Schyler-Italic.ttf 93 | # style: italic 94 | # - family: Trajan Pro 95 | # fonts: 96 | # - asset: fonts/TrajanPro.ttf 97 | # - asset: fonts/TrajanPro_Bold.ttf 98 | # weight: 700 99 | # 100 | # For details regarding fonts from package dependencies, 101 | # see https://flutter.dev/custom-fonts/#from-packages 102 | -------------------------------------------------------------------------------- /test/storage_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:donation_tracker/_services/nhost_service.dart'; 2 | import 'package:test/test.dart'; 3 | 4 | main() { 5 | test('login success', () async { 6 | final server = NhostService(); 7 | await server.loginUser('mail@devshelpdevs.org', 'staging'); 8 | final fileList = await server.getAvailableFiles(); 9 | fileList.forEach((element) { 10 | print(element.fileName); 11 | }); 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:donation_tracker/main.dart'; 9 | import 'package:flutter/material.dart'; 10 | import 'package:flutter_test/flutter_test.dart'; 11 | 12 | void main() { 13 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 14 | // Build our app and trigger a frame. 15 | await tester.pumpWidget(MyApp()); 16 | 17 | // Verify that our counter starts at 0. 18 | expect(find.text('0'), findsOneWidget); 19 | expect(find.text('1'), findsNothing); 20 | 21 | // Tap the '+' icon and trigger a frame. 22 | await tester.tap(find.byIcon(Icons.add)); 23 | await tester.pump(); 24 | 25 | // Verify that our counter has incremented. 26 | expect(find.text('0'), findsNothing); 27 | expect(find.text('1'), findsOneWidget); 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /web/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 -------------------------------------------------------------------------------- /web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/web/favicon.ico -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/web/favicon.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | donation_tracker 35 | 36 | 37 | 38 | 39 | 40 |
41 |

Please wait

42 |
43 |
44 | 47 | --> 55 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /web/loader.css: -------------------------------------------------------------------------------- 1 | body{ 2 | margin: 0; 3 | } 4 | 5 | #loader { 6 | width: 100vw; 7 | height: 100vh; 8 | /* display: block; */ 9 | display: flex; 10 | flex-direction: column; 11 | justify-content: center; 12 | justify-items: center; 13 | align-items: center; 14 | align-content: center; 15 | background-color: #14142B; 16 | } 17 | 18 | #loader-title { 19 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, 20 | Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; 21 | 22 | font-weight: 500; 23 | font-size: 22; 24 | color: white; 25 | } 26 | 27 | .lds-roller { 28 | display: inline-block; 29 | position: relative; 30 | width: 80px; 31 | height: 80px; 32 | } 33 | .lds-roller div { 34 | animation: lds-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; 35 | transform-origin: 40px 40px; 36 | } 37 | .lds-roller div:after { 38 | content: " "; 39 | display: block; 40 | position: absolute; 41 | width: 7px; 42 | height: 7px; 43 | border-radius: 50%; 44 | background: #fff; 45 | margin: -4px 0 0 -4px; 46 | } 47 | .lds-roller div:nth-child(1) { 48 | animation-delay: -0.036s; 49 | } 50 | .lds-roller div:nth-child(1):after { 51 | top: 63px; 52 | left: 63px; 53 | } 54 | .lds-roller div:nth-child(2) { 55 | animation-delay: -0.072s; 56 | } 57 | .lds-roller div:nth-child(2):after { 58 | top: 68px; 59 | left: 56px; 60 | } 61 | .lds-roller div:nth-child(3) { 62 | animation-delay: -0.108s; 63 | } 64 | .lds-roller div:nth-child(3):after { 65 | top: 71px; 66 | left: 48px; 67 | } 68 | .lds-roller div:nth-child(4) { 69 | animation-delay: -0.144s; 70 | } 71 | .lds-roller div:nth-child(4):after { 72 | top: 72px; 73 | left: 40px; 74 | } 75 | .lds-roller div:nth-child(5) { 76 | animation-delay: -0.18s; 77 | } 78 | .lds-roller div:nth-child(5):after { 79 | top: 71px; 80 | left: 32px; 81 | } 82 | .lds-roller div:nth-child(6) { 83 | animation-delay: -0.216s; 84 | } 85 | .lds-roller div:nth-child(6):after { 86 | top: 68px; 87 | left: 24px; 88 | } 89 | .lds-roller div:nth-child(7) { 90 | animation-delay: -0.252s; 91 | } 92 | .lds-roller div:nth-child(7):after { 93 | top: 63px; 94 | left: 17px; 95 | } 96 | .lds-roller div:nth-child(8) { 97 | animation-delay: -0.288s; 98 | } 99 | .lds-roller div:nth-child(8):after { 100 | top: 56px; 101 | left: 12px; 102 | } 103 | @keyframes lds-roller { 104 | 0% { 105 | transform: rotate(0deg); 106 | } 107 | 100% { 108 | transform: rotate(360deg); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DevsHelpDevs Donation Tracker", 3 | "short_name": "DevsHelpDevs Donation Tracker", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "DevsHelpDevs Donation Tracker", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | -------------------------------------------------------------------------------- /windows/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(donation_tracker LANGUAGES CXX) 3 | 4 | set(BINARY_NAME "donation_tracker") 5 | 6 | cmake_policy(SET CMP0063 NEW) 7 | 8 | set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") 9 | 10 | # Configure build options. 11 | get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) 12 | if(IS_MULTICONFIG) 13 | set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" 14 | CACHE STRING "" FORCE) 15 | else() 16 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 17 | set(CMAKE_BUILD_TYPE "Debug" CACHE 18 | STRING "Flutter build mode" FORCE) 19 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS 20 | "Debug" "Profile" "Release") 21 | endif() 22 | endif() 23 | 24 | set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") 25 | set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") 26 | set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") 27 | set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") 28 | 29 | # Use Unicode for all projects. 30 | add_definitions(-DUNICODE -D_UNICODE) 31 | 32 | # Compilation settings that should be applied to most targets. 33 | function(APPLY_STANDARD_SETTINGS TARGET) 34 | target_compile_features(${TARGET} PUBLIC cxx_std_17) 35 | target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") 36 | target_compile_options(${TARGET} PRIVATE /EHsc) 37 | target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") 38 | target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") 39 | endfunction() 40 | 41 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") 42 | 43 | # Flutter library and tool build rules. 44 | add_subdirectory(${FLUTTER_MANAGED_DIR}) 45 | 46 | # Application build 47 | add_subdirectory("runner") 48 | 49 | # Generated plugin build rules, which manage building the plugins and adding 50 | # them to the application. 51 | include(flutter/generated_plugins.cmake) 52 | 53 | 54 | # === Installation === 55 | # Support files are copied into place next to the executable, so that it can 56 | # run in place. This is done instead of making a separate bundle (as on Linux) 57 | # so that building and running from within Visual Studio will work. 58 | set(BUILD_BUNDLE_DIR "$") 59 | # Make the "install" step default, as it's required to run. 60 | set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) 61 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 62 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) 63 | endif() 64 | 65 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") 66 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") 67 | 68 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" 69 | COMPONENT Runtime) 70 | 71 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 72 | COMPONENT Runtime) 73 | 74 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 75 | COMPONENT Runtime) 76 | 77 | if(PLUGIN_BUNDLED_LIBRARIES) 78 | install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" 79 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 80 | COMPONENT Runtime) 81 | endif() 82 | 83 | # Fully re-copy the assets directory on each build to avoid having stale files 84 | # from a previous install. 85 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets") 86 | install(CODE " 87 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") 88 | " COMPONENT Runtime) 89 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" 90 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) 91 | 92 | # Install the AOT library on non-Debug builds only. 93 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 94 | CONFIGURATIONS Profile;Release 95 | COMPONENT Runtime) 96 | -------------------------------------------------------------------------------- /windows/flutter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | 3 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") 4 | 5 | # Configuration provided via flutter tool. 6 | include(${EPHEMERAL_DIR}/generated_config.cmake) 7 | 8 | # TODO: Move the rest of this into files in ephemeral. See 9 | # https://github.com/flutter/flutter/issues/57146. 10 | set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") 11 | 12 | # === Flutter Library === 13 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") 14 | 15 | # Published to parent scope for install step. 16 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) 17 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) 18 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) 19 | set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) 20 | 21 | list(APPEND FLUTTER_LIBRARY_HEADERS 22 | "flutter_export.h" 23 | "flutter_windows.h" 24 | "flutter_messenger.h" 25 | "flutter_plugin_registrar.h" 26 | "flutter_texture_registrar.h" 27 | ) 28 | list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") 29 | add_library(flutter INTERFACE) 30 | target_include_directories(flutter INTERFACE 31 | "${EPHEMERAL_DIR}" 32 | ) 33 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") 34 | add_dependencies(flutter flutter_assemble) 35 | 36 | # === Wrapper === 37 | list(APPEND CPP_WRAPPER_SOURCES_CORE 38 | "core_implementations.cc" 39 | "standard_codec.cc" 40 | ) 41 | list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") 42 | list(APPEND CPP_WRAPPER_SOURCES_PLUGIN 43 | "plugin_registrar.cc" 44 | ) 45 | list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") 46 | list(APPEND CPP_WRAPPER_SOURCES_APP 47 | "flutter_engine.cc" 48 | "flutter_view_controller.cc" 49 | ) 50 | list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") 51 | 52 | # Wrapper sources needed for a plugin. 53 | add_library(flutter_wrapper_plugin STATIC 54 | ${CPP_WRAPPER_SOURCES_CORE} 55 | ${CPP_WRAPPER_SOURCES_PLUGIN} 56 | ) 57 | apply_standard_settings(flutter_wrapper_plugin) 58 | set_target_properties(flutter_wrapper_plugin PROPERTIES 59 | POSITION_INDEPENDENT_CODE ON) 60 | set_target_properties(flutter_wrapper_plugin PROPERTIES 61 | CXX_VISIBILITY_PRESET hidden) 62 | target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) 63 | target_include_directories(flutter_wrapper_plugin PUBLIC 64 | "${WRAPPER_ROOT}/include" 65 | ) 66 | add_dependencies(flutter_wrapper_plugin flutter_assemble) 67 | 68 | # Wrapper sources needed for the runner. 69 | add_library(flutter_wrapper_app STATIC 70 | ${CPP_WRAPPER_SOURCES_CORE} 71 | ${CPP_WRAPPER_SOURCES_APP} 72 | ) 73 | apply_standard_settings(flutter_wrapper_app) 74 | target_link_libraries(flutter_wrapper_app PUBLIC flutter) 75 | target_include_directories(flutter_wrapper_app PUBLIC 76 | "${WRAPPER_ROOT}/include" 77 | ) 78 | add_dependencies(flutter_wrapper_app flutter_assemble) 79 | 80 | # === Flutter tool backend === 81 | # _phony_ is a non-existent file to force this command to run every time, 82 | # since currently there's no way to get a full input/output list from the 83 | # flutter tool. 84 | set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") 85 | set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) 86 | add_custom_command( 87 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} 88 | ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} 89 | ${CPP_WRAPPER_SOURCES_APP} 90 | ${PHONY_OUTPUT} 91 | COMMAND ${CMAKE_COMMAND} -E env 92 | ${FLUTTER_TOOL_ENVIRONMENT} 93 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" 94 | windows-x64 $ 95 | VERBATIM 96 | ) 97 | add_custom_target(flutter_assemble DEPENDS 98 | "${FLUTTER_LIBRARY}" 99 | ${FLUTTER_LIBRARY_HEADERS} 100 | ${CPP_WRAPPER_SOURCES_CORE} 101 | ${CPP_WRAPPER_SOURCES_PLUGIN} 102 | ${CPP_WRAPPER_SOURCES_APP} 103 | ) 104 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/README: -------------------------------------------------------------------------------- 1 | This code is intended to be built into plugins and applications to provide 2 | higher-level, C++ abstractions for interacting with the Flutter library. 3 | 4 | Over time, the goal is to move more of this code into the library in a way that 5 | provides a usable ABI (e.g., does not use standard library in the interfaces). 6 | 7 | Note that this wrapper is still in early stages. Expect significant churn in 8 | both the APIs and the structure of the wrapper (e.g., the exact set of files 9 | that need to be built). 10 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/binary_messenger_impl.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_BINARY_MESSENGER_IMPL_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_BINARY_MESSENGER_IMPL_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include "include/flutter/binary_messenger.h" 14 | 15 | namespace flutter { 16 | 17 | // Wrapper around a FlutterDesktopMessengerRef that implements the 18 | // BinaryMessenger API. 19 | class BinaryMessengerImpl : public BinaryMessenger { 20 | public: 21 | explicit BinaryMessengerImpl(FlutterDesktopMessengerRef core_messenger); 22 | 23 | virtual ~BinaryMessengerImpl(); 24 | 25 | // Prevent copying. 26 | BinaryMessengerImpl(BinaryMessengerImpl const&) = delete; 27 | BinaryMessengerImpl& operator=(BinaryMessengerImpl const&) = delete; 28 | 29 | // |flutter::BinaryMessenger| 30 | void Send(const std::string& channel, 31 | const uint8_t* message, 32 | size_t message_size, 33 | BinaryReply reply) const override; 34 | 35 | // |flutter::BinaryMessenger| 36 | void SetMessageHandler(const std::string& channel, 37 | BinaryMessageHandler handler) override; 38 | 39 | private: 40 | // Handle for interacting with the C API. 41 | FlutterDesktopMessengerRef messenger_; 42 | 43 | // A map from channel names to the BinaryMessageHandler that should be called 44 | // for incoming messages on that channel. 45 | std::map handlers_; 46 | }; 47 | 48 | } // namespace flutter 49 | 50 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_BINARY_MESSENGER_IMPL_H_ 51 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/byte_buffer_streams.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_BYTE_BUFFER_STREAMS_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_BYTE_BUFFER_STREAMS_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "include/flutter/byte_streams.h" 15 | 16 | namespace flutter { 17 | 18 | // Implementation of ByteStreamReader base on a byte array. 19 | class ByteBufferStreamReader : public ByteStreamReader { 20 | public: 21 | // Createa a reader reading from |bytes|, which must have a length of |size|. 22 | // |bytes| must remain valid for the lifetime of this object. 23 | explicit ByteBufferStreamReader(const uint8_t* bytes, size_t size) 24 | : bytes_(bytes), size_(size) {} 25 | 26 | virtual ~ByteBufferStreamReader() = default; 27 | 28 | // |ByteStreamReader| 29 | uint8_t ReadByte() override { 30 | if (location_ >= size_) { 31 | std::cerr << "Invalid read in StandardCodecByteStreamReader" << std::endl; 32 | return 0; 33 | } 34 | return bytes_[location_++]; 35 | } 36 | 37 | // |ByteStreamReader| 38 | void ReadBytes(uint8_t* buffer, size_t length) override { 39 | if (location_ + length > size_) { 40 | std::cerr << "Invalid read in StandardCodecByteStreamReader" << std::endl; 41 | return; 42 | } 43 | std::memcpy(buffer, &bytes_[location_], length); 44 | location_ += length; 45 | } 46 | 47 | // |ByteStreamReader| 48 | void ReadAlignment(uint8_t alignment) override { 49 | uint8_t mod = location_ % alignment; 50 | if (mod) { 51 | location_ += alignment - mod; 52 | } 53 | } 54 | 55 | private: 56 | // The buffer to read from. 57 | const uint8_t* bytes_; 58 | // The total size of the buffer. 59 | size_t size_; 60 | // The current read location. 61 | size_t location_ = 0; 62 | }; 63 | 64 | // Implementation of ByteStreamWriter based on a byte array. 65 | class ByteBufferStreamWriter : public ByteStreamWriter { 66 | public: 67 | // Creates a writer that writes into |buffer|. 68 | // |buffer| must remain valid for the lifetime of this object. 69 | explicit ByteBufferStreamWriter(std::vector* buffer) 70 | : bytes_(buffer) { 71 | assert(buffer); 72 | } 73 | 74 | virtual ~ByteBufferStreamWriter() = default; 75 | 76 | // |ByteStreamWriter| 77 | void WriteByte(uint8_t byte) { bytes_->push_back(byte); } 78 | 79 | // |ByteStreamWriter| 80 | void WriteBytes(const uint8_t* bytes, size_t length) { 81 | assert(length > 0); 82 | bytes_->insert(bytes_->end(), bytes, bytes + length); 83 | } 84 | 85 | // |ByteStreamWriter| 86 | void WriteAlignment(uint8_t alignment) { 87 | uint8_t mod = bytes_->size() % alignment; 88 | if (mod) { 89 | for (int i = 0; i < alignment - mod; ++i) { 90 | WriteByte(0); 91 | } 92 | } 93 | } 94 | 95 | private: 96 | // The buffer to write to. 97 | std::vector* bytes_; 98 | }; 99 | 100 | } // namespace flutter 101 | 102 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_BYTE_BUFFER_STREAMS_H_ 103 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/byte_stream_wrappers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_STREAM_WRAPPERS_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_STREAM_WRAPPERS_H_ 7 | 8 | // Utility classes for interacting with a buffer of bytes as a stream, for use 9 | // in message channel codecs. 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace flutter { 17 | 18 | // Wraps an array of bytes with utility methods for treating it as a readable 19 | // stream. 20 | class ByteBufferStreamReader { 21 | public: 22 | // Createa a reader reading from |bytes|, which must have a length of |size|. 23 | // |bytes| must remain valid for the lifetime of this object. 24 | explicit ByteBufferStreamReader(const uint8_t* bytes, size_t size) 25 | : bytes_(bytes), size_(size) {} 26 | 27 | // Reads and returns the next byte from the stream. 28 | uint8_t ReadByte() { 29 | if (location_ >= size_) { 30 | std::cerr << "Invalid read in StandardCodecByteStreamReader" << std::endl; 31 | return 0; 32 | } 33 | return bytes_[location_++]; 34 | } 35 | 36 | // Reads the next |length| bytes from the stream into |buffer|. The caller 37 | // is responsible for ensuring that |buffer| is large enough. 38 | void ReadBytes(uint8_t* buffer, size_t length) { 39 | if (location_ + length > size_) { 40 | std::cerr << "Invalid read in StandardCodecByteStreamReader" << std::endl; 41 | return; 42 | } 43 | std::memcpy(buffer, &bytes_[location_], length); 44 | location_ += length; 45 | } 46 | 47 | // Advances the read cursor to the next multiple of |alignment| relative to 48 | // the start of the wrapped byte buffer, unless it is already aligned. 49 | void ReadAlignment(uint8_t alignment) { 50 | uint8_t mod = location_ % alignment; 51 | if (mod) { 52 | location_ += alignment - mod; 53 | } 54 | } 55 | 56 | private: 57 | // The buffer to read from. 58 | const uint8_t* bytes_; 59 | // The total size of the buffer. 60 | size_t size_; 61 | // The current read location. 62 | size_t location_ = 0; 63 | }; 64 | 65 | // Wraps an array of bytes with utility methods for treating it as a writable 66 | // stream. 67 | class ByteBufferStreamWriter { 68 | public: 69 | // Createa a writter that writes into |buffer|. 70 | // |buffer| must remain valid for the lifetime of this object. 71 | explicit ByteBufferStreamWriter(std::vector* buffer) 72 | : bytes_(buffer) { 73 | assert(buffer); 74 | } 75 | 76 | // Writes |byte| to the wrapped buffer. 77 | void WriteByte(uint8_t byte) { bytes_->push_back(byte); } 78 | 79 | // Writes the next |length| bytes from |bytes| into the wrapped buffer. 80 | // The caller is responsible for ensuring that |buffer| is large enough. 81 | void WriteBytes(const uint8_t* bytes, size_t length) { 82 | assert(length > 0); 83 | bytes_->insert(bytes_->end(), bytes, bytes + length); 84 | } 85 | 86 | // Writes 0s until the next multiple of |alignment| relative to 87 | // the start of the wrapped byte buffer, unless the write positition is 88 | // already aligned. 89 | void WriteAlignment(uint8_t alignment) { 90 | uint8_t mod = bytes_->size() % alignment; 91 | if (mod) { 92 | for (int i = 0; i < alignment - mod; ++i) { 93 | WriteByte(0); 94 | } 95 | } 96 | } 97 | 98 | private: 99 | // The buffer to write to. 100 | std::vector* bytes_; 101 | }; 102 | 103 | } // namespace flutter 104 | 105 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_STREAM_WRAPPERS_H_ 106 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/engine_method_result.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This file is deprecated in favor of core_implementations.cc. This is a 6 | // temporary forwarding implementation so that the switch to 7 | // core_implementations.cc isn't an immediate breaking change, allowing for the 8 | // template to be updated to include it and update the template version before 9 | // removing this file. 10 | 11 | #include "core_implementations.cc" 12 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/flutter_engine.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "include/flutter/flutter_engine.h" 6 | 7 | #include 8 | #include 9 | 10 | #include "binary_messenger_impl.h" 11 | 12 | namespace flutter { 13 | 14 | FlutterEngine::FlutterEngine(const DartProject& project) { 15 | FlutterDesktopEngineProperties c_engine_properties = {}; 16 | c_engine_properties.assets_path = project.assets_path().c_str(); 17 | c_engine_properties.icu_data_path = project.icu_data_path().c_str(); 18 | c_engine_properties.aot_library_path = project.aot_library_path().c_str(); 19 | 20 | const std::vector& entrypoint_args = 21 | project.dart_entrypoint_arguments(); 22 | std::vector entrypoint_argv; 23 | std::transform( 24 | entrypoint_args.begin(), entrypoint_args.end(), 25 | std::back_inserter(entrypoint_argv), 26 | [](const std::string& arg) -> const char* { return arg.c_str(); }); 27 | 28 | c_engine_properties.dart_entrypoint_argc = 29 | static_cast(entrypoint_argv.size()); 30 | c_engine_properties.dart_entrypoint_argv = 31 | entrypoint_argv.size() > 0 ? entrypoint_argv.data() : nullptr; 32 | 33 | engine_ = FlutterDesktopEngineCreate(&c_engine_properties); 34 | 35 | auto core_messenger = FlutterDesktopEngineGetMessenger(engine_); 36 | messenger_ = std::make_unique(core_messenger); 37 | } 38 | 39 | FlutterEngine::~FlutterEngine() { 40 | ShutDown(); 41 | } 42 | 43 | bool FlutterEngine::Run(const char* entry_point) { 44 | if (!engine_) { 45 | std::cerr << "Cannot run an engine that failed creation." << std::endl; 46 | return false; 47 | } 48 | if (has_been_run_) { 49 | std::cerr << "Cannot run an engine more than once." << std::endl; 50 | return false; 51 | } 52 | bool run_succeeded = FlutterDesktopEngineRun(engine_, entry_point); 53 | if (!run_succeeded) { 54 | std::cerr << "Failed to start engine." << std::endl; 55 | } 56 | has_been_run_ = true; 57 | return run_succeeded; 58 | } 59 | 60 | void FlutterEngine::ShutDown() { 61 | if (engine_ && owns_engine_) { 62 | FlutterDesktopEngineDestroy(engine_); 63 | } 64 | engine_ = nullptr; 65 | } 66 | 67 | #ifndef WINUWP 68 | std::chrono::nanoseconds FlutterEngine::ProcessMessages() { 69 | return std::chrono::nanoseconds(FlutterDesktopEngineProcessMessages(engine_)); 70 | } 71 | #endif 72 | 73 | void FlutterEngine::ReloadSystemFonts() { 74 | FlutterDesktopEngineReloadSystemFonts(engine_); 75 | } 76 | 77 | FlutterDesktopPluginRegistrarRef FlutterEngine::GetRegistrarForPlugin( 78 | const std::string& plugin_name) { 79 | if (!engine_) { 80 | std::cerr << "Cannot get plugin registrar on an engine that isn't running; " 81 | "call Run first." 82 | << std::endl; 83 | return nullptr; 84 | } 85 | return FlutterDesktopEngineGetPluginRegistrar(engine_, plugin_name.c_str()); 86 | } 87 | 88 | FlutterDesktopEngineRef FlutterEngine::RelinquishEngine() { 89 | owns_engine_ = false; 90 | return engine_; 91 | } 92 | 93 | } // namespace flutter 94 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/flutter_view_controller.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "include/flutter/flutter_view_controller.h" 6 | 7 | #include 8 | #include 9 | 10 | namespace flutter { 11 | 12 | #ifdef WINUWP 13 | FlutterViewController::FlutterViewController( 14 | ABI::Windows::UI::Core::CoreWindow* window, 15 | ABI::Windows::ApplicationModel::Activation::IActivatedEventArgs* args, 16 | const DartProject& project) { 17 | engine_ = std::make_unique(project); 18 | controller_ = FlutterDesktopViewControllerCreateFromCoreWindow( 19 | window, args, engine_->RelinquishEngine()); 20 | if (!controller_) { 21 | std::cerr << "Failed to create view controller." << std::endl; 22 | return; 23 | } 24 | view_ = std::make_unique( 25 | FlutterDesktopViewControllerGetView(controller_)); 26 | } 27 | #else 28 | FlutterViewController::FlutterViewController(int width, 29 | int height, 30 | const DartProject& project) { 31 | engine_ = std::make_unique(project); 32 | controller_ = FlutterDesktopViewControllerCreate(width, height, 33 | engine_->RelinquishEngine()); 34 | if (!controller_) { 35 | std::cerr << "Failed to create view controller." << std::endl; 36 | return; 37 | } 38 | view_ = std::make_unique( 39 | FlutterDesktopViewControllerGetView(controller_)); 40 | } 41 | #endif 42 | 43 | FlutterViewController::~FlutterViewController() { 44 | if (controller_) { 45 | FlutterDesktopViewControllerDestroy(controller_); 46 | } 47 | } 48 | 49 | #ifndef WINUWP 50 | std::optional FlutterViewController::HandleTopLevelWindowProc( 51 | HWND hwnd, 52 | UINT message, 53 | WPARAM wparam, 54 | LPARAM lparam) { 55 | LRESULT result; 56 | bool handled = FlutterDesktopViewControllerHandleTopLevelWindowProc( 57 | controller_, hwnd, message, wparam, lparam, &result); 58 | return handled ? result : std::optional(std::nullopt); 59 | } 60 | #endif 61 | 62 | } // namespace flutter 63 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/binary_messenger.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_BINARY_MESSENGER_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_BINARY_MESSENGER_H_ 7 | 8 | #include 9 | #include 10 | 11 | namespace flutter { 12 | 13 | // A binary message reply callback. 14 | // 15 | // Used for submitting a binary reply back to a Flutter message sender. 16 | typedef std::function 17 | BinaryReply; 18 | 19 | // A message handler callback. 20 | // 21 | // Used for receiving messages from Flutter and providing an asynchronous reply. 22 | typedef std::function< 23 | void(const uint8_t* message, size_t message_size, BinaryReply reply)> 24 | BinaryMessageHandler; 25 | 26 | // A protocol for a class that handles communication of binary data on named 27 | // channels to and from the Flutter engine. 28 | class BinaryMessenger { 29 | public: 30 | virtual ~BinaryMessenger() = default; 31 | 32 | // Sends a binary message to the Flutter engine on the specified channel. 33 | // 34 | // If |reply| is provided, it will be called back with the response from the 35 | // engine. 36 | virtual void Send(const std::string& channel, 37 | const uint8_t* message, 38 | size_t message_size, 39 | BinaryReply reply = nullptr) const = 0; 40 | 41 | // Registers a message handler for incoming binary messages from the Flutter 42 | // side on the specified channel. 43 | // 44 | // Replaces any existing handler. Provide a null handler to unregister the 45 | // existing handler. 46 | virtual void SetMessageHandler(const std::string& channel, 47 | BinaryMessageHandler handler) = 0; 48 | }; 49 | 50 | } // namespace flutter 51 | 52 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_BINARY_MESSENGER_H_ 53 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/byte_streams.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_BYTE_STREAMS_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_BYTE_STREAMS_H_ 7 | 8 | // Interfaces for interacting with a stream of bytes, for use in codecs. 9 | 10 | namespace flutter { 11 | 12 | // An interface for a class that reads from a byte stream. 13 | class ByteStreamReader { 14 | public: 15 | explicit ByteStreamReader() = default; 16 | virtual ~ByteStreamReader() = default; 17 | 18 | // Reads and returns the next byte from the stream. 19 | virtual uint8_t ReadByte() = 0; 20 | 21 | // Reads the next |length| bytes from the stream into |buffer|. The caller 22 | // is responsible for ensuring that |buffer| is large enough. 23 | virtual void ReadBytes(uint8_t* buffer, size_t length) = 0; 24 | 25 | // Advances the read cursor to the next multiple of |alignment| relative to 26 | // the start of the stream, unless it is already aligned. 27 | virtual void ReadAlignment(uint8_t alignment) = 0; 28 | 29 | // Reads and returns the next 32-bit integer from the stream. 30 | int32_t ReadInt32() { 31 | int32_t value = 0; 32 | ReadBytes(reinterpret_cast(&value), 4); 33 | return value; 34 | } 35 | 36 | // Reads and returns the next 64-bit integer from the stream. 37 | int64_t ReadInt64() { 38 | int64_t value = 0; 39 | ReadBytes(reinterpret_cast(&value), 8); 40 | return value; 41 | } 42 | 43 | // Reads and returns the next 64-bit floating point number from the stream. 44 | double ReadDouble() { 45 | double value = 0; 46 | ReadBytes(reinterpret_cast(&value), 8); 47 | return value; 48 | } 49 | }; 50 | 51 | // An interface for a class that writes to a byte stream. 52 | class ByteStreamWriter { 53 | public: 54 | explicit ByteStreamWriter() = default; 55 | virtual ~ByteStreamWriter() = default; 56 | 57 | // Writes |byte| to the stream. 58 | virtual void WriteByte(uint8_t byte) = 0; 59 | 60 | // Writes the next |length| bytes from |bytes| to the stream 61 | virtual void WriteBytes(const uint8_t* bytes, size_t length) = 0; 62 | 63 | // Writes 0s until the next multiple of |alignment| relative to the start 64 | // of the stream, unless the write positition is already aligned. 65 | virtual void WriteAlignment(uint8_t alignment) = 0; 66 | 67 | // Writes the given 32-bit int to the stream. 68 | void WriteInt32(int32_t value) { 69 | WriteBytes(reinterpret_cast(&value), 4); 70 | } 71 | 72 | // Writes the given 64-bit int to the stream. 73 | void WriteInt64(int64_t value) { 74 | WriteBytes(reinterpret_cast(&value), 8); 75 | } 76 | 77 | // Writes the given 36-bit double to the stream. 78 | void WriteDouble(double value) { 79 | WriteBytes(reinterpret_cast(&value), 8); 80 | } 81 | }; 82 | 83 | } // namespace flutter 84 | 85 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_BYTE_STREAMS_H_ 86 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/dart_project.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_DART_PROJECT_H_ 6 | #define FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_DART_PROJECT_H_ 7 | 8 | #include 9 | #include 10 | 11 | namespace flutter { 12 | 13 | // A set of Flutter and Dart assets used to initialize a Flutter engine. 14 | class DartProject { 15 | public: 16 | #ifdef WINUWP 17 | // Creates a DartProject from a series of absolute paths. 18 | // The directory should contain the following top-level items: 19 | // - icudtl.dat (provided as a resource by the Flutter tool) 20 | // - flutter_assets (as built by the Flutter tool) 21 | // - app.so, for an AOT build (as built by the Flutter tool) 22 | // 23 | // The path must be absolute. 24 | explicit DartProject(const std::wstring& assetspath, 25 | const std::wstring& icupath, 26 | const std::wstring& aotpath) { 27 | assets_path_ = assetspath; 28 | icu_data_path_ = icupath; 29 | aot_library_path_ = aotpath; 30 | } 31 | #else 32 | // Creates a DartProject from a directory path. The directory should contain 33 | // the following top-level items: 34 | // - icudtl.dat (provided as a resource by the Flutter tool) 35 | // - flutter_assets (as built by the Flutter tool) 36 | // - app.so, for an AOT build (as built by the Flutter tool) 37 | // 38 | // The path can either be absolute, or relative to the directory containing 39 | // the running executable. 40 | explicit DartProject(const std::wstring& path) { 41 | assets_path_ = path + L"\\flutter_assets"; 42 | icu_data_path_ = path + L"\\icudtl.dat"; 43 | aot_library_path_ = path + L"\\app.so"; 44 | } 45 | #endif 46 | 47 | ~DartProject() = default; 48 | 49 | // Sets the command line arguments that should be passed to the Dart 50 | // entrypoint. 51 | void set_dart_entrypoint_arguments(std::vector arguments) { 52 | dart_entrypoint_arguments_ = std::move(arguments); 53 | } 54 | 55 | // Returns any command line arguments that should be passed to the Dart 56 | // entrypoint. 57 | const std::vector& dart_entrypoint_arguments() const { 58 | return dart_entrypoint_arguments_; 59 | } 60 | 61 | private: 62 | // Accessors for internals are private, so that they can be changed if more 63 | // flexible options for project structures are needed later without it 64 | // being a breaking change. Provide access to internal classes that need 65 | // them. 66 | friend class FlutterEngine; 67 | friend class FlutterViewController; 68 | friend class DartProjectTest; 69 | 70 | const std::wstring& assets_path() const { return assets_path_; } 71 | const std::wstring& icu_data_path() const { return icu_data_path_; } 72 | const std::wstring& aot_library_path() const { return aot_library_path_; } 73 | 74 | // The path to the assets directory. 75 | std::wstring assets_path_; 76 | // The path to the ICU data. 77 | std::wstring icu_data_path_; 78 | // The path to the AOT library. This will always return a path, but non-AOT 79 | // builds will not be expected to actually have a library at that path. 80 | std::wstring aot_library_path_; 81 | // The list of arguments to pass through to the Dart entrypoint. 82 | std::vector dart_entrypoint_arguments_; 83 | }; 84 | 85 | } // namespace flutter 86 | 87 | #endif // FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_DART_PROJECT_H_ 88 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/engine_method_result.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_ENGINE_METHOD_RESULT_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_ENGINE_METHOD_RESULT_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include "binary_messenger.h" 13 | #include "method_codec.h" 14 | #include "method_result.h" 15 | 16 | namespace flutter { 17 | 18 | namespace internal { 19 | // Manages the one-time sending of response data. This is an internal helper 20 | // class for EngineMethodResult, separated out since the implementation doesn't 21 | // vary based on the template type. 22 | class ReplyManager { 23 | public: 24 | ReplyManager(BinaryReply reply_handler_); 25 | ~ReplyManager(); 26 | 27 | // Prevent copying. 28 | ReplyManager(ReplyManager const&) = delete; 29 | ReplyManager& operator=(ReplyManager const&) = delete; 30 | 31 | // Sends the given response data (which must either be nullptr, which 32 | // indicates an unhandled method, or a response serialized with |codec_|) to 33 | // the engine. 34 | void SendResponseData(const std::vector* data); 35 | 36 | private: 37 | BinaryReply reply_handler_; 38 | }; 39 | } // namespace internal 40 | 41 | // Implemention of MethodResult that sends a response to the Flutter engine 42 | // exactly once, encoded using a given codec. 43 | template 44 | class EngineMethodResult : public MethodResult { 45 | public: 46 | // Creates a result object that will send results to |reply_handler|, encoded 47 | // using |codec|. The |codec| pointer must remain valid for as long as this 48 | // object exists. 49 | EngineMethodResult(BinaryReply reply_handler, const MethodCodec* codec) 50 | : reply_manager_( 51 | std::make_unique(std::move(reply_handler))), 52 | codec_(codec) {} 53 | 54 | ~EngineMethodResult() = default; 55 | 56 | protected: 57 | // |flutter::MethodResult| 58 | void SuccessInternal(const T* result) override { 59 | std::unique_ptr> data = 60 | codec_->EncodeSuccessEnvelope(result); 61 | reply_manager_->SendResponseData(data.get()); 62 | } 63 | 64 | // |flutter::MethodResult| 65 | void ErrorInternal(const std::string& error_code, 66 | const std::string& error_message, 67 | const T* error_details) override { 68 | std::unique_ptr> data = 69 | codec_->EncodeErrorEnvelope(error_code, error_message, error_details); 70 | reply_manager_->SendResponseData(data.get()); 71 | } 72 | 73 | // |flutter::MethodResult| 74 | void NotImplementedInternal() override { 75 | reply_manager_->SendResponseData(nullptr); 76 | } 77 | 78 | private: 79 | std::unique_ptr reply_manager_; 80 | 81 | const MethodCodec* codec_; 82 | }; 83 | 84 | } // namespace flutter 85 | 86 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_ENGINE_METHOD_RESULT_H_ 87 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/event_sink.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_SINK_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_SINK_H_ 7 | 8 | namespace flutter { 9 | 10 | class EncodableValue; 11 | 12 | // Event callback. Events to be sent to Flutter application 13 | // act as clients of this interface for sending events. 14 | template 15 | class EventSink { 16 | public: 17 | EventSink() = default; 18 | virtual ~EventSink() = default; 19 | 20 | // Prevent copying. 21 | EventSink(EventSink const&) = delete; 22 | EventSink& operator=(EventSink const&) = delete; 23 | 24 | // Consumes a successful event 25 | void Success(const T& event) { SuccessInternal(&event); } 26 | 27 | // Consumes a successful event. 28 | void Success() { SuccessInternal(nullptr); } 29 | 30 | // Consumes an error event. 31 | void Error(const std::string& error_code, 32 | const std::string& error_message, 33 | const T& error_details) { 34 | ErrorInternal(error_code, error_message, &error_details); 35 | } 36 | 37 | // Consumes an error event. 38 | void Error(const std::string& error_code, 39 | const std::string& error_message = "") { 40 | ErrorInternal(error_code, error_message, nullptr); 41 | } 42 | 43 | // Consumes end of stream. Ensuing calls to Success() or 44 | // Error(), if any, are ignored. 45 | void EndOfStream() { EndOfStreamInternal(); } 46 | 47 | protected: 48 | // Implementation of the public interface, to be provided by subclasses. 49 | virtual void SuccessInternal(const T* event = nullptr) = 0; 50 | 51 | // Implementation of the public interface, to be provided by subclasses. 52 | virtual void ErrorInternal(const std::string& error_code, 53 | const std::string& error_message, 54 | const T* error_details) = 0; 55 | 56 | // Implementation of the public interface, to be provided by subclasses. 57 | virtual void EndOfStreamInternal() = 0; 58 | }; 59 | 60 | } // namespace flutter 61 | 62 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_SINK_H_ 63 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/event_stream_handler.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_STREAM_HANDLER_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_STREAM_HANDLER_H_ 7 | 8 | #include "event_sink.h" 9 | 10 | namespace flutter { 11 | 12 | class EncodableValue; 13 | 14 | template 15 | struct StreamHandlerError { 16 | const std::string& error_code; 17 | const std::string& error_message; 18 | const T* error_details; 19 | 20 | StreamHandlerError(const std::string& error_code, 21 | const std::string& error_message, 22 | const T* error_details) 23 | : error_code(error_code), 24 | error_message(error_message), 25 | error_details(error_details) {} 26 | }; 27 | 28 | // Handler for stream setup and teardown requests. 29 | // Implementations must be prepared to accept sequences of alternating calls to 30 | // OnListen() and OnCancel(). Implementations should ideally consume no 31 | // resources when the last such call is not OnListen(). In typical situations, 32 | // this means that the implementation should register itself with 33 | // platform-specific event sources OnListen() and deregister again OnCancel(). 34 | template 35 | class StreamHandler { 36 | public: 37 | StreamHandler() = default; 38 | virtual ~StreamHandler() = default; 39 | 40 | // Prevent copying. 41 | StreamHandler(StreamHandler const&) = delete; 42 | StreamHandler& operator=(StreamHandler const&) = delete; 43 | 44 | // Handles a request to set up an event stream. Returns nullptr on success, 45 | // or an error on failure. 46 | // |arguments| is stream configuration arguments and 47 | // |events| is an EventSink for emitting events to the Flutter receiver. 48 | std::unique_ptr> OnListen( 49 | const T* arguments, 50 | std::unique_ptr>&& events) { 51 | return OnListenInternal(arguments, std::move(events)); 52 | } 53 | 54 | // Handles a request to tear down the most recently created event stream. 55 | // Returns nullptr on success, or an error on failure. 56 | // |arguments| is stream configuration arguments. 57 | std::unique_ptr> OnCancel(const T* arguments) { 58 | return OnCancelInternal(arguments); 59 | } 60 | 61 | protected: 62 | // Implementation of the public interface, to be provided by subclasses. 63 | virtual std::unique_ptr> OnListenInternal( 64 | const T* arguments, 65 | std::unique_ptr>&& events) = 0; 66 | 67 | // Implementation of the public interface, to be provided by subclasses. 68 | virtual std::unique_ptr> OnCancelInternal( 69 | const T* arguments) = 0; 70 | }; 71 | 72 | } // namespace flutter 73 | 74 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_STREAM_HANDLER_H_ 75 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/event_stream_handler_functions.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_STREAM_HANDLER_FUNCTIONS_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_STREAM_HANDLER_FUNCTIONS_H_ 7 | 8 | #include 9 | 10 | #include "event_sink.h" 11 | #include "event_stream_handler.h" 12 | 13 | namespace flutter { 14 | 15 | class EncodableValue; 16 | 17 | // Handler types for each of the StreamHandler setup and teardown 18 | // requests. 19 | template 20 | using StreamHandlerListen = 21 | std::function>( 22 | const T* arguments, 23 | std::unique_ptr>&& events)>; 24 | 25 | template 26 | using StreamHandlerCancel = 27 | std::function>(const T* arguments)>; 28 | 29 | // An implementation of StreamHandler that pass calls through to 30 | // provided function objects. 31 | template 32 | class StreamHandlerFunctions : public StreamHandler { 33 | public: 34 | // Creates a handler object that calls the provided functions 35 | // for the corresponding StreamHandler outcomes. 36 | StreamHandlerFunctions(StreamHandlerListen on_listen, 37 | StreamHandlerCancel on_cancel) 38 | : on_listen_(on_listen), on_cancel_(on_cancel) {} 39 | 40 | virtual ~StreamHandlerFunctions() = default; 41 | 42 | // Prevent copying. 43 | StreamHandlerFunctions(StreamHandlerFunctions const&) = delete; 44 | StreamHandlerFunctions& operator=(StreamHandlerFunctions const&) = delete; 45 | 46 | protected: 47 | // |flutter::StreamHandler| 48 | std::unique_ptr> OnListenInternal( 49 | const T* arguments, 50 | std::unique_ptr>&& events) override { 51 | if (on_listen_) { 52 | return on_listen_(arguments, std::move(events)); 53 | } 54 | 55 | auto error = std::make_unique>( 56 | "error", "No OnListen handler set", nullptr); 57 | return std::move(error); 58 | } 59 | 60 | // |flutter::StreamHandler| 61 | std::unique_ptr> OnCancelInternal( 62 | const T* arguments) override { 63 | if (on_cancel_) { 64 | return on_cancel_(arguments); 65 | } 66 | 67 | auto error = std::make_unique>( 68 | "error", "No OnCancel handler set", nullptr); 69 | return std::move(error); 70 | } 71 | 72 | StreamHandlerListen on_listen_; 73 | StreamHandlerCancel on_cancel_; 74 | }; 75 | 76 | } // namespace flutter 77 | 78 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_STREAM_HANDLER_FUNCTIONS_H_ 79 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/flutter_engine.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_ENGINE_H_ 6 | #define FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_ENGINE_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include "binary_messenger.h" 15 | #include "dart_project.h" 16 | #include "plugin_registrar.h" 17 | #include "plugin_registry.h" 18 | 19 | namespace flutter { 20 | 21 | // An instance of a Flutter engine. 22 | // 23 | // In the future, this will be the API surface used for all interactions with 24 | // the engine, rather than having them duplicated on FlutterViewController. 25 | // For now it is only used in the rare where you need a headless Flutter engine. 26 | class FlutterEngine : public PluginRegistry { 27 | public: 28 | // Creates a new engine for running the given project. 29 | explicit FlutterEngine(const DartProject& project); 30 | 31 | virtual ~FlutterEngine(); 32 | 33 | // Prevent copying. 34 | FlutterEngine(FlutterEngine const&) = delete; 35 | FlutterEngine& operator=(FlutterEngine const&) = delete; 36 | 37 | // Starts running the engine, with an optional entry point. 38 | // 39 | // If provided, entry_point must be the name of a top-level function from the 40 | // same Dart library that contains the app's main() function, and must be 41 | // decorated with `@pragma(vm:entry-point)` to ensure the method is not 42 | // tree-shaken by the Dart compiler. If not provided, defaults to main(). 43 | bool Run(const char* entry_point = nullptr); 44 | 45 | // Terminates the running engine. 46 | void ShutDown(); 47 | 48 | // Processes any pending events in the Flutter engine, and returns the 49 | // nanosecond delay until the next scheduled event (or max, if none). 50 | // 51 | // This should be called on every run of the application-level runloop, and 52 | // a wait for native events in the runloop should never be longer than the 53 | // last return value from this function. 54 | std::chrono::nanoseconds ProcessMessages(); 55 | 56 | // Tells the engine that the system font list has changed. Should be called 57 | // by clients when OS-level font changes happen (e.g., WM_FONTCHANGE in a 58 | // Win32 application). 59 | void ReloadSystemFonts(); 60 | 61 | // flutter::PluginRegistry: 62 | FlutterDesktopPluginRegistrarRef GetRegistrarForPlugin( 63 | const std::string& plugin_name) override; 64 | 65 | // Returns the messenger to use for creating channels to communicate with the 66 | // Flutter engine. 67 | // 68 | // This pointer will remain valid for the lifetime of this instance. 69 | BinaryMessenger* messenger() { return messenger_.get(); } 70 | 71 | private: 72 | // For access to RelinquishEngine. 73 | friend class FlutterViewController; 74 | 75 | // Gives up ownership of |engine_|, but keeps a weak reference to it. 76 | // 77 | // This is intended to be used by FlutterViewController, since the underlying 78 | // C API for view controllers takes over engine ownership. 79 | FlutterDesktopEngineRef RelinquishEngine(); 80 | 81 | // Handle for interacting with the C API's engine reference. 82 | FlutterDesktopEngineRef engine_ = nullptr; 83 | 84 | // Messenger for communicating with the engine. 85 | std::unique_ptr messenger_; 86 | 87 | // Whether or not this wrapper owns |engine_|. 88 | bool owns_engine_ = true; 89 | 90 | // Whether the engine has been run. This will be true if Run has been called, 91 | // or if RelinquishEngine has been called (since the view controller will 92 | // run the engine if it hasn't already been run). 93 | bool has_been_run_ = false; 94 | }; 95 | 96 | } // namespace flutter 97 | 98 | #endif // FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_ENGINE_H_ 99 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/flutter_view.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_VIEW_H_ 6 | #define FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_VIEW_H_ 7 | 8 | #include 9 | 10 | namespace flutter { 11 | 12 | // A view displaying Flutter content. 13 | class FlutterView { 14 | public: 15 | explicit FlutterView(FlutterDesktopViewRef view) : view_(view) {} 16 | 17 | virtual ~FlutterView() = default; 18 | 19 | // Prevent copying. 20 | FlutterView(FlutterView const&) = delete; 21 | FlutterView& operator=(FlutterView const&) = delete; 22 | 23 | #ifndef WINUWP 24 | // Returns the backing HWND for the view. 25 | HWND GetNativeWindow() { return FlutterDesktopViewGetHWND(view_); } 26 | #endif 27 | 28 | private: 29 | // Handle for interacting with the C API's view. 30 | FlutterDesktopViewRef view_ = nullptr; 31 | }; 32 | 33 | } // namespace flutter 34 | 35 | #endif // FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_VIEW_H_ 36 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/flutter_view_controller.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_VIEW_CONTROLLER_H_ 6 | #define FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_VIEW_CONTROLLER_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include "dart_project.h" 15 | #include "flutter_engine.h" 16 | #include "flutter_view.h" 17 | #include "plugin_registrar.h" 18 | #include "plugin_registry.h" 19 | 20 | #ifdef WINUWP 21 | #include 22 | #include 23 | #endif 24 | 25 | namespace flutter { 26 | 27 | // A controller for a view displaying Flutter content. 28 | // 29 | // This is the primary wrapper class for the desktop C API. 30 | // If you use this class, you should not call any of the setup or teardown 31 | // methods in the C API directly, as this class will do that internally. 32 | class FlutterViewController { 33 | public: 34 | #ifndef WINUWP 35 | // Creates a FlutterView that can be parented into a Windows View hierarchy 36 | // either using HWNDs. 37 | // 38 | // |dart_project| will be used to configure the engine backing this view. 39 | explicit FlutterViewController(int width, 40 | int height, 41 | const DartProject& project); 42 | #else 43 | // Creates a FlutterView that can be parented into a Windows View hierarchy 44 | // either using CoreWindow. 45 | // 46 | // |dart_project| will be used to configure the engine backing this view. 47 | // |IActivatedEventArgs| will be used to configure the engine switches. Can 48 | // be set to nullptr. 49 | explicit FlutterViewController( 50 | ABI::Windows::UI::Core::CoreWindow* window, 51 | ABI::Windows::ApplicationModel::Activation::IActivatedEventArgs* args, 52 | const DartProject& project); 53 | #endif 54 | 55 | virtual ~FlutterViewController(); 56 | 57 | // Prevent copying. 58 | FlutterViewController(FlutterViewController const&) = delete; 59 | FlutterViewController& operator=(FlutterViewController const&) = delete; 60 | 61 | // Returns the engine running Flutter content in this view. 62 | FlutterEngine* engine() { return engine_.get(); } 63 | 64 | // Returns the view managed by this controller. 65 | FlutterView* view() { return view_.get(); } 66 | 67 | #ifndef WINUWP 68 | // Allows the Flutter engine and any interested plugins an opportunity to 69 | // handle the given message. 70 | // 71 | // If a result is returned, then the message was handled in such a way that 72 | // further handling should not be done. 73 | std::optional HandleTopLevelWindowProc(HWND hwnd, 74 | UINT message, 75 | WPARAM wparam, 76 | LPARAM lparam); 77 | #endif 78 | 79 | private: 80 | // Handle for interacting with the C API's view controller, if any. 81 | FlutterDesktopViewControllerRef controller_ = nullptr; 82 | 83 | // The backing engine 84 | std::unique_ptr engine_; 85 | 86 | // The owned FlutterView. 87 | std::unique_ptr view_; 88 | }; 89 | 90 | } // namespace flutter 91 | 92 | #endif // FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_VIEW_CONTROLLER_H_ 93 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/json_message_codec.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_JSON_MESSAGE_CODEC_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_JSON_MESSAGE_CODEC_H_ 7 | 8 | #include "json_type.h" 9 | #include "message_codec.h" 10 | 11 | namespace flutter { 12 | 13 | // A message encoding/decoding mechanism for communications to/from the 14 | // Flutter engine via JSON channels. 15 | class JsonMessageCodec : public MessageCodec { 16 | public: 17 | // Returns the shared instance of the codec. 18 | static const JsonMessageCodec& GetInstance(); 19 | 20 | ~JsonMessageCodec() = default; 21 | 22 | // Prevent copying. 23 | JsonMessageCodec(JsonMessageCodec const&) = delete; 24 | JsonMessageCodec& operator=(JsonMessageCodec const&) = delete; 25 | 26 | protected: 27 | // Instances should be obtained via GetInstance. 28 | JsonMessageCodec() = default; 29 | 30 | // |flutter::MessageCodec| 31 | std::unique_ptr DecodeMessageInternal( 32 | const uint8_t* binary_message, 33 | const size_t message_size) const override; 34 | 35 | // |flutter::MessageCodec| 36 | std::unique_ptr> EncodeMessageInternal( 37 | const JsonValueType& message) const override; 38 | }; 39 | 40 | } // namespace flutter 41 | 42 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_JSON_MESSAGE_CODEC_H_ 43 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/json_method_codec.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_JSON_METHOD_CODEC_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_JSON_METHOD_CODEC_H_ 7 | 8 | #include "json_type.h" 9 | #include "method_call.h" 10 | #include "method_codec.h" 11 | 12 | namespace flutter { 13 | 14 | // An implementation of MethodCodec that uses JSON strings as the serialization. 15 | class JsonMethodCodec : public MethodCodec { 16 | public: 17 | // Returns the shared instance of the codec. 18 | static const JsonMethodCodec& GetInstance(); 19 | 20 | ~JsonMethodCodec() = default; 21 | 22 | // Prevent copying. 23 | JsonMethodCodec(JsonMethodCodec const&) = delete; 24 | JsonMethodCodec& operator=(JsonMethodCodec const&) = delete; 25 | 26 | protected: 27 | // Instances should be obtained via GetInstance. 28 | JsonMethodCodec() = default; 29 | 30 | // |flutter::MethodCodec| 31 | std::unique_ptr> DecodeMethodCallInternal( 32 | const uint8_t* message, 33 | const size_t message_size) const override; 34 | 35 | // |flutter::MethodCodec| 36 | std::unique_ptr> EncodeMethodCallInternal( 37 | const MethodCall& method_call) const override; 38 | 39 | // |flutter::MethodCodec| 40 | std::unique_ptr> EncodeSuccessEnvelopeInternal( 41 | const JsonValueType* result) const override; 42 | 43 | // |flutter::MethodCodec| 44 | std::unique_ptr> EncodeErrorEnvelopeInternal( 45 | const std::string& error_code, 46 | const std::string& error_message, 47 | const JsonValueType* error_details) const override; 48 | }; 49 | 50 | } // namespace flutter 51 | 52 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_JSON_METHOD_CODEC_H_ 53 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/json_type.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_JSON_TYPE_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_JSON_TYPE_H_ 7 | 8 | // By default, the Json codecs use jsoncpp, but a version using RapidJSON is 9 | // implemented as well. To use the latter, set USE_RAPID_JSON. 10 | // 11 | // When writing code using the JSON codec classes, do not use JsonValueType; 12 | // instead use the underlying type for the library you have selected directly. 13 | 14 | #ifdef USE_RAPID_JSON 15 | #include 16 | 17 | // The APIs often pass owning references, which in RapidJSON must include the 18 | // allocator, so the value type for the APIs is Document rather than Value. 19 | using JsonValueType = rapidjson::Document; 20 | #else 21 | #include 22 | 23 | using JsonValueType = Json::Value; 24 | #endif 25 | 26 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_JSON_TYPE_H_ 27 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/message_codec.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_MESSAGE_CODEC_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_MESSAGE_CODEC_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace flutter { 13 | 14 | // Translates between a binary message and higher-level method call and 15 | // response/error objects. 16 | template 17 | class MessageCodec { 18 | public: 19 | MessageCodec() = default; 20 | 21 | virtual ~MessageCodec() = default; 22 | 23 | // Prevent copying. 24 | MessageCodec(MessageCodec const&) = delete; 25 | MessageCodec& operator=(MessageCodec const&) = delete; 26 | 27 | // Returns the message encoded in |binary_message|, or nullptr if it cannot be 28 | // decoded by this codec. 29 | std::unique_ptr DecodeMessage(const uint8_t* binary_message, 30 | const size_t message_size) const { 31 | return std::move(DecodeMessageInternal(binary_message, message_size)); 32 | } 33 | 34 | // Returns the message encoded in |binary_message|, or nullptr if it cannot be 35 | // decoded by this codec. 36 | std::unique_ptr DecodeMessage( 37 | const std::vector& binary_message) const { 38 | size_t size = binary_message.size(); 39 | const uint8_t* data = size > 0 ? &binary_message[0] : nullptr; 40 | return std::move(DecodeMessageInternal(data, size)); 41 | } 42 | 43 | // Returns a binary encoding of the given |message|, or nullptr if the 44 | // message cannot be serialized by this codec. 45 | std::unique_ptr> EncodeMessage(const T& message) const { 46 | return std::move(EncodeMessageInternal(message)); 47 | } 48 | 49 | protected: 50 | // Implementation of the public interface, to be provided by subclasses. 51 | virtual std::unique_ptr DecodeMessageInternal( 52 | const uint8_t* binary_message, 53 | const size_t message_size) const = 0; 54 | 55 | // Implementation of the public interface, to be provided by subclasses. 56 | virtual std::unique_ptr> EncodeMessageInternal( 57 | const T& message) const = 0; 58 | }; 59 | 60 | } // namespace flutter 61 | 62 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_MESSAGE_CODEC_H_ 63 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/method_call.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_TYPED_METHOD_CALL_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_TYPED_METHOD_CALL_H_ 7 | 8 | #include 9 | #include 10 | 11 | namespace flutter { 12 | 13 | class EncodableValue; 14 | 15 | // An object encapsulating a method call from Flutter whose arguments are of 16 | // type T. 17 | template 18 | class MethodCall { 19 | public: 20 | // Creates a MethodCall with the given name and arguments. 21 | MethodCall(const std::string& method_name, std::unique_ptr arguments) 22 | : method_name_(method_name), arguments_(std::move(arguments)) {} 23 | 24 | virtual ~MethodCall() = default; 25 | 26 | // Prevent copying. 27 | MethodCall(MethodCall const&) = delete; 28 | MethodCall& operator=(MethodCall const&) = delete; 29 | 30 | // The name of the method being called. 31 | const std::string& method_name() const { return method_name_; } 32 | 33 | // The arguments to the method call, or NULL if there are none. 34 | const T* arguments() const { return arguments_.get(); } 35 | 36 | private: 37 | std::string method_name_; 38 | std::unique_ptr arguments_; 39 | }; 40 | 41 | } // namespace flutter 42 | 43 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_TYPED_METHOD_CALL_H_ 44 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/method_result.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_RESULT_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_RESULT_H_ 7 | 8 | #include 9 | 10 | namespace flutter { 11 | 12 | class EncodableValue; 13 | 14 | // Encapsulates a result returned from a MethodCall. Only one method should be 15 | // called on any given instance. 16 | template 17 | class MethodResult { 18 | public: 19 | MethodResult() = default; 20 | 21 | virtual ~MethodResult() = default; 22 | 23 | // Prevent copying. 24 | MethodResult(MethodResult const&) = delete; 25 | MethodResult& operator=(MethodResult const&) = delete; 26 | 27 | // Sends a success response, indicating that the call completed successfully 28 | // with the given result. 29 | void Success(const T& result) { SuccessInternal(&result); } 30 | 31 | // Sends a success response, indicating that the call completed successfully 32 | // with no result. 33 | void Success() { SuccessInternal(nullptr); } 34 | 35 | // Sends an error response, indicating that the call was understood but 36 | // handling failed in some way. 37 | // 38 | // error_code: A string error code describing the error. 39 | // error_message: A user-readable error message. 40 | // error_details: Arbitrary extra details about the error. 41 | void Error(const std::string& error_code, 42 | const std::string& error_message, 43 | const T& error_details) { 44 | ErrorInternal(error_code, error_message, &error_details); 45 | } 46 | 47 | // Sends an error response, indicating that the call was understood but 48 | // handling failed in some way. 49 | // 50 | // error_code: A string error code describing the error. 51 | // error_message: A user-readable error message (optional). 52 | void Error(const std::string& error_code, 53 | const std::string& error_message = "") { 54 | ErrorInternal(error_code, error_message, nullptr); 55 | } 56 | 57 | // Sends a not-implemented response, indicating that the method either was not 58 | // recognized, or has not been implemented. 59 | void NotImplemented() { NotImplementedInternal(); } 60 | 61 | protected: 62 | // Implementation of the public interface, to be provided by subclasses. 63 | virtual void SuccessInternal(const T* result) = 0; 64 | 65 | // Implementation of the public interface, to be provided by subclasses. 66 | virtual void ErrorInternal(const std::string& error_code, 67 | const std::string& error_message, 68 | const T* error_details) = 0; 69 | 70 | // Implementation of the public interface, to be provided by subclasses. 71 | virtual void NotImplementedInternal() = 0; 72 | }; 73 | 74 | } // namespace flutter 75 | 76 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_RESULT_H_ 77 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/method_result_functions.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_RESULT_FUNCTIONS_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_RESULT_FUNCTIONS_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "method_result.h" 12 | 13 | namespace flutter { 14 | 15 | class EncodableValue; 16 | 17 | // Handler types for each of the MethodResult outcomes. 18 | template 19 | using ResultHandlerSuccess = std::function; 20 | template 21 | using ResultHandlerError = std::function; 24 | template 25 | using ResultHandlerNotImplemented = std::function; 26 | 27 | // An implementation of MethodResult that pass calls through to provided 28 | // function objects, for ease of constructing one-off result handlers. 29 | template 30 | class MethodResultFunctions : public MethodResult { 31 | public: 32 | // Creates a result object that calls the provided functions for the 33 | // corresponding MethodResult outcomes. 34 | MethodResultFunctions(ResultHandlerSuccess on_success, 35 | ResultHandlerError on_error, 36 | ResultHandlerNotImplemented on_not_implemented) 37 | : on_success_(on_success), 38 | on_error_(on_error), 39 | on_not_implemented_(on_not_implemented) {} 40 | 41 | virtual ~MethodResultFunctions() = default; 42 | 43 | // Prevent copying. 44 | MethodResultFunctions(MethodResultFunctions const&) = delete; 45 | MethodResultFunctions& operator=(MethodResultFunctions const&) = delete; 46 | 47 | protected: 48 | // |flutter::MethodResult| 49 | void SuccessInternal(const T* result) override { 50 | if (on_success_) { 51 | on_success_(result); 52 | } 53 | } 54 | 55 | // |flutter::MethodResult| 56 | void ErrorInternal(const std::string& error_code, 57 | const std::string& error_message, 58 | const T* error_details) override { 59 | if (on_error_) { 60 | on_error_(error_code, error_message, error_details); 61 | } 62 | } 63 | 64 | // |flutter::MethodResult| 65 | void NotImplementedInternal() override { 66 | if (on_not_implemented_) { 67 | on_not_implemented_(); 68 | } 69 | } 70 | 71 | private: 72 | ResultHandlerSuccess on_success_; 73 | ResultHandlerError on_error_; 74 | ResultHandlerNotImplemented on_not_implemented_; 75 | }; 76 | 77 | } // namespace flutter 78 | 79 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_RESULT_FUNCTIONS_H_ 80 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/plugin_registry.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRY_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRY_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace flutter { 13 | 14 | // Vends PluginRegistrars for named plugins. 15 | // 16 | // Plugins are identified by unique string keys, typically the name of the 17 | // plugin's main class. 18 | class PluginRegistry { 19 | public: 20 | PluginRegistry() = default; 21 | virtual ~PluginRegistry() = default; 22 | 23 | // Prevent copying. 24 | PluginRegistry(PluginRegistry const&) = delete; 25 | PluginRegistry& operator=(PluginRegistry const&) = delete; 26 | 27 | // Returns the FlutterDesktopPluginRegistrarRef to register a plugin with the 28 | // given name. 29 | // 30 | // The name must be unique across the application. 31 | virtual FlutterDesktopPluginRegistrarRef GetRegistrarForPlugin( 32 | const std::string& plugin_name) = 0; 33 | }; 34 | 35 | } // namespace flutter 36 | 37 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRY_H_ 38 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/standard_codec_serializer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_CODEC_SERIALIZER_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_CODEC_SERIALIZER_H_ 7 | 8 | #include "byte_streams.h" 9 | #include "encodable_value.h" 10 | 11 | namespace flutter { 12 | 13 | // Encapsulates the logic for encoding/decoding EncodableValues to/from the 14 | // standard codec binary representation. 15 | // 16 | // This can be subclassed to extend the standard codec with support for new 17 | // types. 18 | class StandardCodecSerializer { 19 | public: 20 | virtual ~StandardCodecSerializer(); 21 | 22 | // Returns the shared serializer instance. 23 | static const StandardCodecSerializer& GetInstance(); 24 | 25 | // Prevent copying. 26 | StandardCodecSerializer(StandardCodecSerializer const&) = delete; 27 | StandardCodecSerializer& operator=(StandardCodecSerializer const&) = delete; 28 | 29 | // Reads and returns the next value from |stream|. 30 | EncodableValue ReadValue(ByteStreamReader* stream) const; 31 | 32 | // Writes the encoding of |value| to |stream|, including the initial type 33 | // discrimination byte. 34 | // 35 | // Can be overridden by a subclass to extend the codec. 36 | virtual void WriteValue(const EncodableValue& value, 37 | ByteStreamWriter* stream) const; 38 | 39 | protected: 40 | // Codecs require long-lived serializers, so clients should always use 41 | // GetInstance(). 42 | StandardCodecSerializer(); 43 | 44 | // Reads and returns the next value from |stream|, whose discrimination byte 45 | // was |type|. 46 | // 47 | // The discrimination byte will already have been read from the stream when 48 | // this is called. 49 | // 50 | // Can be overridden by a subclass to extend the codec. 51 | virtual EncodableValue ReadValueOfType(uint8_t type, 52 | ByteStreamReader* stream) const; 53 | 54 | // Reads the variable-length size from the current position in |stream|. 55 | size_t ReadSize(ByteStreamReader* stream) const; 56 | 57 | // Writes the variable-length size encoding to |stream|. 58 | void WriteSize(size_t size, ByteStreamWriter* stream) const; 59 | 60 | private: 61 | // Reads a fixed-type list whose values are of type T from the current 62 | // position in |stream|, and returns it as the corresponding EncodableValue. 63 | // |T| must correspond to one of the supported list value types of 64 | // EncodableValue. 65 | template 66 | EncodableValue ReadVector(ByteStreamReader* stream) const; 67 | 68 | // Writes |vector| to |stream| as a fixed-type list. |T| must correspond to 69 | // one of the supported list value types of EncodableValue. 70 | template 71 | void WriteVector(const std::vector vector, ByteStreamWriter* stream) const; 72 | }; 73 | 74 | } // namespace flutter 75 | 76 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_CODEC_SERIALIZER_H_ 77 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/standard_message_codec.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_MESSAGE_CODEC_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_MESSAGE_CODEC_H_ 7 | 8 | #include 9 | 10 | #include "encodable_value.h" 11 | #include "message_codec.h" 12 | #include "standard_codec_serializer.h" 13 | 14 | namespace flutter { 15 | 16 | // A binary message encoding/decoding mechanism for communications to/from the 17 | // Flutter engine via message channels. 18 | class StandardMessageCodec : public MessageCodec { 19 | public: 20 | // Returns an instance of the codec, optionally using a custom serializer to 21 | // add support for more types. 22 | // 23 | // If provided, |serializer| must be long-lived. If no serializer is provided, 24 | // the default will be used. 25 | // 26 | // The instance returned for a given |serializer| will be shared, and 27 | // any instance returned from this will be long-lived, and can be safely 28 | // passed to, e.g., channel constructors. 29 | static const StandardMessageCodec& GetInstance( 30 | const StandardCodecSerializer* serializer = nullptr); 31 | 32 | ~StandardMessageCodec(); 33 | 34 | // Prevent copying. 35 | StandardMessageCodec(StandardMessageCodec const&) = delete; 36 | StandardMessageCodec& operator=(StandardMessageCodec const&) = delete; 37 | 38 | protected: 39 | // |flutter::MessageCodec| 40 | std::unique_ptr DecodeMessageInternal( 41 | const uint8_t* binary_message, 42 | const size_t message_size) const override; 43 | 44 | // |flutter::MessageCodec| 45 | std::unique_ptr> EncodeMessageInternal( 46 | const EncodableValue& message) const override; 47 | 48 | private: 49 | // Instances should be obtained via GetInstance. 50 | explicit StandardMessageCodec(const StandardCodecSerializer* serializer); 51 | 52 | const StandardCodecSerializer* serializer_; 53 | }; 54 | 55 | } // namespace flutter 56 | 57 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_MESSAGE_CODEC_H_ 58 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/standard_method_codec.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_METHOD_CODEC_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_METHOD_CODEC_H_ 7 | 8 | #include 9 | 10 | #include "encodable_value.h" 11 | #include "method_call.h" 12 | #include "method_codec.h" 13 | #include "standard_codec_serializer.h" 14 | 15 | namespace flutter { 16 | 17 | // An implementation of MethodCodec that uses a binary serialization. 18 | class StandardMethodCodec : public MethodCodec { 19 | public: 20 | // Returns an instance of the codec, optionally using a custom serializer to 21 | // add support for more types. 22 | // 23 | // If provided, |serializer| must be long-lived. If no serializer is provided, 24 | // the default will be used. 25 | // 26 | // The instance returned for a given |extension| will be shared, and 27 | // any instance returned from this will be long-lived, and can be safely 28 | // passed to, e.g., channel constructors. 29 | static const StandardMethodCodec& GetInstance( 30 | const StandardCodecSerializer* serializer = nullptr); 31 | 32 | ~StandardMethodCodec(); 33 | 34 | // Prevent copying. 35 | StandardMethodCodec(StandardMethodCodec const&) = delete; 36 | StandardMethodCodec& operator=(StandardMethodCodec const&) = delete; 37 | 38 | protected: 39 | // |flutter::MethodCodec| 40 | std::unique_ptr> DecodeMethodCallInternal( 41 | const uint8_t* message, 42 | size_t message_size) const override; 43 | 44 | // |flutter::MethodCodec| 45 | std::unique_ptr> EncodeMethodCallInternal( 46 | const MethodCall& method_call) const override; 47 | 48 | // |flutter::MethodCodec| 49 | std::unique_ptr> EncodeSuccessEnvelopeInternal( 50 | const EncodableValue* result) const override; 51 | 52 | // |flutter::MethodCodec| 53 | std::unique_ptr> EncodeErrorEnvelopeInternal( 54 | const std::string& error_code, 55 | const std::string& error_message, 56 | const EncodableValue* error_details) const override; 57 | 58 | // |flutter::MethodCodec| 59 | bool DecodeAndProcessResponseEnvelopeInternal( 60 | const uint8_t* response, 61 | size_t response_size, 62 | MethodResult* result) const override; 63 | 64 | private: 65 | // Instances should be obtained via GetInstance. 66 | explicit StandardMethodCodec(const StandardCodecSerializer* serializer); 67 | 68 | const StandardCodecSerializer* serializer_; 69 | }; 70 | 71 | } // namespace flutter 72 | 73 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_METHOD_CODEC_H_ 74 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/include/flutter/texture_registrar.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_TEXTURE_REGISTRAR_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_TEXTURE_REGISTRAR_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace flutter { 16 | 17 | // A pixel buffer texture. 18 | class PixelBufferTexture { 19 | public: 20 | // A callback used for retrieving pixel buffers. 21 | typedef std::function 23 | CopyBufferCallback; 24 | 25 | // Creates a pixel buffer texture that uses the provided |copy_buffer_cb| to 26 | // retrieve the buffer. 27 | // As the callback is usually invoked from the render thread, the callee must 28 | // take care of proper synchronization. It also needs to be ensured that the 29 | // returned buffer isn't released prior to unregistering this texture. 30 | PixelBufferTexture(CopyBufferCallback copy_buffer_callback) 31 | : copy_buffer_callback_(copy_buffer_callback) {} 32 | 33 | // Returns the callback-provided FlutterDesktopPixelBuffer that contains the 34 | // actual pixel data. The intended surface size is specified by |width| and 35 | // |height|. 36 | const FlutterDesktopPixelBuffer* CopyPixelBuffer(size_t width, 37 | size_t height) const { 38 | return copy_buffer_callback_(width, height); 39 | } 40 | 41 | private: 42 | const CopyBufferCallback copy_buffer_callback_; 43 | }; 44 | 45 | // The available texture variants. 46 | // Only PixelBufferTexture is currently implemented. 47 | // Other variants are expected to be added in the future. 48 | typedef std::variant TextureVariant; 49 | 50 | // An object keeping track of external textures. 51 | // 52 | // Thread safety: 53 | // It's safe to call the member methods from any thread. 54 | class TextureRegistrar { 55 | public: 56 | virtual ~TextureRegistrar() = default; 57 | 58 | // Registers a |texture| object and returns the ID for that texture. 59 | virtual int64_t RegisterTexture(TextureVariant* texture) = 0; 60 | 61 | // Notifies the flutter engine that the texture object corresponding 62 | // to |texure_id| needs to render a new frame. 63 | // 64 | // For PixelBufferTextures, this will effectively make the engine invoke 65 | // the callback that was provided upon creating the texture. 66 | virtual bool MarkTextureFrameAvailable(int64_t texture_id) = 0; 67 | 68 | // Unregisters an existing Texture object. 69 | // Textures must not be unregistered while they're in use. 70 | virtual bool UnregisterTexture(int64_t texture_id) = 0; 71 | }; 72 | 73 | } // namespace flutter 74 | 75 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_TEXTURE_REGISTRAR_H_ 76 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/json_message_codec.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "include/flutter/json_message_codec.h" 6 | 7 | #include 8 | #include 9 | 10 | #ifdef USE_RAPID_JSON 11 | #include "rapidjson/error/en.h" 12 | #include "rapidjson/stringbuffer.h" 13 | #include "rapidjson/writer.h" 14 | #endif 15 | 16 | namespace flutter { 17 | 18 | // static 19 | const JsonMessageCodec& JsonMessageCodec::GetInstance() { 20 | static JsonMessageCodec sInstance; 21 | return sInstance; 22 | } 23 | 24 | std::unique_ptr> JsonMessageCodec::EncodeMessageInternal( 25 | const JsonValueType& message) const { 26 | #ifdef USE_RAPID_JSON 27 | // TODO: Look into alternate writers that would avoid the buffer copy. 28 | rapidjson::StringBuffer buffer; 29 | rapidjson::Writer writer(buffer); 30 | message.Accept(writer); 31 | const char* buffer_start = buffer.GetString(); 32 | return std::make_unique>( 33 | buffer_start, buffer_start + buffer.GetSize()); 34 | #else 35 | Json::StreamWriterBuilder writer_builder; 36 | std::string serialization = Json::writeString(writer_builder, message); 37 | return std::make_unique>(serialization.begin(), 38 | serialization.end()); 39 | #endif 40 | } 41 | 42 | std::unique_ptr JsonMessageCodec::DecodeMessageInternal( 43 | const uint8_t* binary_message, 44 | const size_t message_size) const { 45 | auto raw_message = reinterpret_cast(binary_message); 46 | auto json_message = std::make_unique(); 47 | std::string parse_errors; 48 | bool parsing_successful = false; 49 | #ifdef USE_RAPID_JSON 50 | rapidjson::ParseResult result = 51 | json_message->Parse(raw_message, message_size); 52 | parsing_successful = result == rapidjson::ParseErrorCode::kParseErrorNone; 53 | if (!parsing_successful) { 54 | parse_errors = rapidjson::GetParseError_En(result.Code()); 55 | } 56 | #else 57 | Json::CharReaderBuilder reader_builder; 58 | std::unique_ptr parser(reader_builder.newCharReader()); 59 | parsing_successful = parser->parse(raw_message, raw_message + message_size, 60 | json_message.get(), &parse_errors); 61 | #endif 62 | if (!parsing_successful) { 63 | std::cerr << "Unable to parse JSON message:" << std::endl 64 | << parse_errors << std::endl; 65 | return nullptr; 66 | } 67 | return json_message; 68 | } 69 | 70 | } // namespace flutter 71 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/plugin_registrar.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "include/flutter/plugin_registrar.h" 6 | 7 | #include 8 | #include 9 | 10 | #include "binary_messenger_impl.h" 11 | #include "include/flutter/engine_method_result.h" 12 | #include "include/flutter/method_channel.h" 13 | #include "texture_registrar_impl.h" 14 | 15 | namespace flutter { 16 | 17 | // ===== PluginRegistrar ===== 18 | 19 | PluginRegistrar::PluginRegistrar(FlutterDesktopPluginRegistrarRef registrar) 20 | : registrar_(registrar) { 21 | auto core_messenger = FlutterDesktopPluginRegistrarGetMessenger(registrar_); 22 | messenger_ = std::make_unique(core_messenger); 23 | 24 | auto texture_registrar = 25 | FlutterDesktopRegistrarGetTextureRegistrar(registrar_); 26 | texture_registrar_ = 27 | std::make_unique(texture_registrar); 28 | } 29 | 30 | PluginRegistrar::~PluginRegistrar() { 31 | // This must always be the first call. 32 | ClearPlugins(); 33 | 34 | // Explicitly cleared to facilitate testing of destruction order. 35 | messenger_.reset(); 36 | } 37 | 38 | void PluginRegistrar::AddPlugin(std::unique_ptr plugin) { 39 | plugins_.insert(std::move(plugin)); 40 | } 41 | 42 | void PluginRegistrar::ClearPlugins() { 43 | plugins_.clear(); 44 | } 45 | 46 | // ===== PluginRegistrarManager ===== 47 | 48 | // static 49 | PluginRegistrarManager* PluginRegistrarManager::GetInstance() { 50 | static PluginRegistrarManager* instance = new PluginRegistrarManager(); 51 | return instance; 52 | } 53 | 54 | PluginRegistrarManager::PluginRegistrarManager() = default; 55 | 56 | // static 57 | void PluginRegistrarManager::OnRegistrarDestroyed( 58 | FlutterDesktopPluginRegistrarRef registrar) { 59 | GetInstance()->registrars()->erase(registrar); 60 | } 61 | 62 | } // namespace flutter 63 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/standard_codec_serializer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_ENCODABLE_VALUE_SERIALIZER_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_ENCODABLE_VALUE_SERIALIZER_H_ 7 | 8 | #include "byte_stream_wrappers.h" 9 | #include "include/flutter/encodable_value.h" 10 | 11 | namespace flutter { 12 | 13 | // Encapsulates the logic for encoding/decoding EncodableValues to/from the 14 | // standard codec binary representation. 15 | class StandardCodecSerializer { 16 | public: 17 | StandardCodecSerializer(); 18 | ~StandardCodecSerializer(); 19 | 20 | // Prevent copying. 21 | StandardCodecSerializer(StandardCodecSerializer const&) = delete; 22 | StandardCodecSerializer& operator=(StandardCodecSerializer const&) = delete; 23 | 24 | // Reads and returns the next value from |stream|. 25 | EncodableValue ReadValue(ByteBufferStreamReader* stream) const; 26 | 27 | // Writes the encoding of |value| to |stream|. 28 | void WriteValue(const EncodableValue& value, 29 | ByteBufferStreamWriter* stream) const; 30 | 31 | protected: 32 | // Reads the variable-length size from the current position in |stream|. 33 | size_t ReadSize(ByteBufferStreamReader* stream) const; 34 | 35 | // Writes the variable-length size encoding to |stream|. 36 | void WriteSize(size_t size, ByteBufferStreamWriter* stream) const; 37 | 38 | // Reads a fixed-type list whose values are of type T from the current 39 | // position in |stream|, and returns it as the corresponding EncodableValue. 40 | // |T| must correspond to one of the support list value types of 41 | // EncodableValue. 42 | template 43 | EncodableValue ReadVector(ByteBufferStreamReader* stream) const; 44 | 45 | // Writes |vector| to |stream| as a fixed-type list. |T| must correspond to 46 | // one of the support list value types of EncodableValue. 47 | template 48 | void WriteVector(const std::vector vector, 49 | ByteBufferStreamWriter* stream) const; 50 | }; 51 | 52 | } // namespace flutter 53 | 54 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_ENCODABLE_VALUE_SERIALIZER_H_ 55 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/cpp_client_wrapper/texture_registrar_impl.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_TEXTURE_REGISTRAR_IMPL_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_TEXTURE_REGISTRAR_IMPL_H_ 7 | 8 | #include "include/flutter/texture_registrar.h" 9 | 10 | namespace flutter { 11 | 12 | // Wrapper around a FlutterDesktopTextureRegistrarRef that implements the 13 | // TextureRegistrar API. 14 | class TextureRegistrarImpl : public TextureRegistrar { 15 | public: 16 | explicit TextureRegistrarImpl( 17 | FlutterDesktopTextureRegistrarRef texture_registrar_ref); 18 | virtual ~TextureRegistrarImpl(); 19 | 20 | // Prevent copying. 21 | TextureRegistrarImpl(TextureRegistrarImpl const&) = delete; 22 | TextureRegistrarImpl& operator=(TextureRegistrarImpl const&) = delete; 23 | 24 | // |flutter::TextureRegistrar| 25 | int64_t RegisterTexture(TextureVariant* texture) override; 26 | 27 | // |flutter::TextureRegistrar| 28 | bool MarkTextureFrameAvailable(int64_t texture_id) override; 29 | 30 | // |flutter::TextureRegistrar| 31 | bool UnregisterTexture(int64_t texture_id) override; 32 | 33 | private: 34 | // Handle for interacting with the C API. 35 | FlutterDesktopTextureRegistrarRef texture_registrar_ref_; 36 | }; 37 | 38 | } // namespace flutter 39 | 40 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_TEXTURE_REGISTRAR_IMPL_H_ 41 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/flutter_export.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_EXPORT_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_EXPORT_H_ 7 | 8 | #ifdef FLUTTER_DESKTOP_LIBRARY 9 | // Add visibility/export annotations when building the library. 10 | 11 | #ifdef _WIN32 12 | #define FLUTTER_EXPORT __declspec(dllexport) 13 | #else 14 | #define FLUTTER_EXPORT __attribute__((visibility("default"))) 15 | #endif 16 | 17 | #else // FLUTTER_DESKTOP_LIBRARY 18 | 19 | // Add import annotations when consuming the library. 20 | #ifdef _WIN32 21 | #define FLUTTER_EXPORT __declspec(dllimport) 22 | #else 23 | #define FLUTTER_EXPORT 24 | #endif 25 | 26 | #endif // FLUTTER_DESKTOP_LIBRARY 27 | 28 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_EXPORT_H_ 29 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/flutter_messenger.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_MESSENGER_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_MESSENGER_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "flutter_export.h" 12 | 13 | #if defined(__cplusplus) 14 | extern "C" { 15 | #endif // defined(__cplusplus) 16 | 17 | // Opaque reference to a Flutter engine messenger. 18 | typedef struct FlutterDesktopMessenger* FlutterDesktopMessengerRef; 19 | 20 | // Opaque handle for tracking responses to messages. 21 | typedef struct _FlutterPlatformMessageResponseHandle 22 | FlutterDesktopMessageResponseHandle; 23 | 24 | // The callback expected as a response of a binary message. 25 | typedef void (*FlutterDesktopBinaryReply)(const uint8_t* data, 26 | size_t data_size, 27 | void* user_data); 28 | 29 | // A message received from Flutter. 30 | typedef struct { 31 | // Size of this struct as created by Flutter. 32 | size_t struct_size; 33 | // The name of the channel used for this message. 34 | const char* channel; 35 | // The raw message data. 36 | const uint8_t* message; 37 | // The length of |message|. 38 | size_t message_size; 39 | // The response handle. If non-null, the receiver of this message must call 40 | // FlutterDesktopSendMessageResponse exactly once with this handle. 41 | const FlutterDesktopMessageResponseHandle* response_handle; 42 | } FlutterDesktopMessage; 43 | 44 | // Function pointer type for message handler callback registration. 45 | // 46 | // The user data will be whatever was passed to FlutterDesktopSetMessageHandler 47 | // for the channel the message is received on. 48 | typedef void (*FlutterDesktopMessageCallback)( 49 | FlutterDesktopMessengerRef /* messenger */, 50 | const FlutterDesktopMessage* /* message*/, 51 | void* /* user data */); 52 | 53 | // Sends a binary message to the Flutter side on the specified channel. 54 | FLUTTER_EXPORT bool FlutterDesktopMessengerSend( 55 | FlutterDesktopMessengerRef messenger, 56 | const char* channel, 57 | const uint8_t* message, 58 | const size_t message_size); 59 | 60 | FLUTTER_EXPORT bool FlutterDesktopMessengerSendWithReply( 61 | FlutterDesktopMessengerRef messenger, 62 | const char* channel, 63 | const uint8_t* message, 64 | const size_t message_size, 65 | const FlutterDesktopBinaryReply reply, 66 | void* user_data); 67 | 68 | // Sends a reply to a FlutterDesktopMessage for the given response handle. 69 | // 70 | // Once this has been called, |handle| is invalid and must not be used again. 71 | FLUTTER_EXPORT void FlutterDesktopMessengerSendResponse( 72 | FlutterDesktopMessengerRef messenger, 73 | const FlutterDesktopMessageResponseHandle* handle, 74 | const uint8_t* data, 75 | size_t data_length); 76 | 77 | // Registers a callback function for incoming binary messages from the Flutter 78 | // side on the specified channel. 79 | // 80 | // Replaces any existing callback. Provide a null handler to unregister the 81 | // existing callback. 82 | // 83 | // If |user_data| is provided, it will be passed in |callback| calls. 84 | FLUTTER_EXPORT void FlutterDesktopMessengerSetCallback( 85 | FlutterDesktopMessengerRef messenger, 86 | const char* channel, 87 | FlutterDesktopMessageCallback callback, 88 | void* user_data); 89 | 90 | #if defined(__cplusplus) 91 | } // extern "C" 92 | #endif 93 | 94 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_MESSENGER_H_ 95 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/flutter_plugin_registrar.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_PLUGIN_REGISTRAR_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_PLUGIN_REGISTRAR_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "flutter_export.h" 12 | #include "flutter_messenger.h" 13 | #include "flutter_texture_registrar.h" 14 | 15 | #if defined(__cplusplus) 16 | extern "C" { 17 | #endif // defined(__cplusplus) 18 | 19 | // Opaque reference to a plugin registrar. 20 | typedef struct FlutterDesktopPluginRegistrar* FlutterDesktopPluginRegistrarRef; 21 | 22 | // Function pointer type for registrar destruction callback. 23 | typedef void (*FlutterDesktopOnPluginRegistrarDestroyed)( 24 | FlutterDesktopPluginRegistrarRef); 25 | 26 | // Returns the engine messenger associated with this registrar. 27 | FLUTTER_EXPORT FlutterDesktopMessengerRef 28 | FlutterDesktopPluginRegistrarGetMessenger( 29 | FlutterDesktopPluginRegistrarRef registrar); 30 | 31 | // Returns the texture registrar associated with this registrar. 32 | FLUTTER_EXPORT FlutterDesktopTextureRegistrarRef 33 | FlutterDesktopRegistrarGetTextureRegistrar( 34 | FlutterDesktopPluginRegistrarRef registrar); 35 | 36 | // Registers a callback to be called when the plugin registrar is destroyed. 37 | FLUTTER_EXPORT void FlutterDesktopPluginRegistrarSetDestructionHandler( 38 | FlutterDesktopPluginRegistrarRef registrar, 39 | FlutterDesktopOnPluginRegistrarDestroyed callback); 40 | 41 | #if defined(__cplusplus) 42 | } // extern "C" 43 | #endif 44 | 45 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_PLUGIN_REGISTRAR_H_ 46 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/flutter_texture_registrar.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_TEXTURE_REGISTRAR_H_ 6 | #define FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_TEXTURE_REGISTRAR_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "flutter_export.h" 12 | 13 | #if defined(__cplusplus) 14 | extern "C" { 15 | #endif 16 | 17 | struct FlutterDesktopTextureRegistrar; 18 | // Opaque reference to a texture registrar. 19 | typedef struct FlutterDesktopTextureRegistrar* 20 | FlutterDesktopTextureRegistrarRef; 21 | 22 | // Possible values for the type specified in FlutterDesktopTextureInfo. 23 | // Additional types may be added in the future. 24 | typedef enum { 25 | // A Pixel buffer-based texture. 26 | kFlutterDesktopPixelBufferTexture 27 | } FlutterDesktopTextureType; 28 | 29 | // An image buffer object. 30 | typedef struct { 31 | // The pixel data buffer. 32 | const uint8_t* buffer; 33 | // Width of the pixel buffer. 34 | size_t width; 35 | // Height of the pixel buffer. 36 | size_t height; 37 | } FlutterDesktopPixelBuffer; 38 | 39 | // The pixel buffer copy callback definition provided to 40 | // the Flutter engine to copy the texture. 41 | // It is invoked with the intended surface size specified by |width| and 42 | // |height| and the |user_data| held by FlutterDesktopPixelBufferTextureConfig. 43 | // 44 | // As this is usually called from the render thread, the callee must take 45 | // care of proper synchronization. It also needs to be ensured that the 46 | // returned FlutterDesktopPixelBuffer isn't released prior to unregistering 47 | // the corresponding texture. 48 | typedef const FlutterDesktopPixelBuffer* ( 49 | *FlutterDesktopPixelBufferTextureCallback)(size_t width, 50 | size_t height, 51 | void* user_data); 52 | 53 | // An object used to configure pixel buffer textures. 54 | typedef struct { 55 | // The callback used by the engine to copy the pixel buffer object. 56 | FlutterDesktopPixelBufferTextureCallback callback; 57 | // Opaque data that will get passed to the provided |callback|. 58 | void* user_data; 59 | } FlutterDesktopPixelBufferTextureConfig; 60 | 61 | typedef struct { 62 | FlutterDesktopTextureType type; 63 | union { 64 | FlutterDesktopPixelBufferTextureConfig pixel_buffer_config; 65 | }; 66 | } FlutterDesktopTextureInfo; 67 | 68 | // Registers a new texture with the Flutter engine and returns the texture ID. 69 | // This function can be called from any thread. 70 | FLUTTER_EXPORT int64_t FlutterDesktopTextureRegistrarRegisterExternalTexture( 71 | FlutterDesktopTextureRegistrarRef texture_registrar, 72 | const FlutterDesktopTextureInfo* info); 73 | 74 | // Unregisters an existing texture from the Flutter engine for a |texture_id|. 75 | // Returns true on success or false if the specified texture doesn't exist. 76 | // This function can be called from any thread. 77 | // However, textures must not be unregistered while they're in use. 78 | FLUTTER_EXPORT bool FlutterDesktopTextureRegistrarUnregisterExternalTexture( 79 | FlutterDesktopTextureRegistrarRef texture_registrar, 80 | int64_t texture_id); 81 | 82 | // Marks that a new texture frame is available for a given |texture_id|. 83 | // Returns true on success or false if the specified texture doesn't exist. 84 | // This function can be called from any thread. 85 | FLUTTER_EXPORT bool 86 | FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable( 87 | FlutterDesktopTextureRegistrarRef texture_registrar, 88 | int64_t texture_id); 89 | 90 | #if defined(__cplusplus) 91 | } // extern "C" 92 | #endif 93 | 94 | #endif // FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_TEXTURE_REGISTRAR_H_ 95 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/flutter_windows.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/windows/flutter/ephemeral/flutter_windows.dll -------------------------------------------------------------------------------- /windows/flutter/ephemeral/flutter_windows.dll.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/windows/flutter/ephemeral/flutter_windows.dll.lib -------------------------------------------------------------------------------- /windows/flutter/ephemeral/icudtl.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/windows/flutter/ephemeral/icudtl.dat -------------------------------------------------------------------------------- /windows/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | dropfiles_window 7 | file_selector_windows 8 | url_launcher_windows 9 | ) 10 | 11 | set(PLUGIN_BUNDLED_LIBRARIES) 12 | 13 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 14 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 15 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 16 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 18 | endforeach(plugin) 19 | -------------------------------------------------------------------------------- /windows/runner/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(runner LANGUAGES CXX) 3 | 4 | add_executable(${BINARY_NAME} WIN32 5 | "flutter_window.cpp" 6 | "main.cpp" 7 | "run_loop.cpp" 8 | "utils.cpp" 9 | "win32_window.cpp" 10 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 11 | "Runner.rc" 12 | "runner.exe.manifest" 13 | ) 14 | apply_standard_settings(${BINARY_NAME}) 15 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") 16 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) 17 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") 18 | add_dependencies(${BINARY_NAME} flutter_assemble) 19 | -------------------------------------------------------------------------------- /windows/runner/Runner.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #pragma code_page(65001) 4 | #include "resource.h" 5 | 6 | #define APSTUDIO_READONLY_SYMBOLS 7 | ///////////////////////////////////////////////////////////////////////////// 8 | // 9 | // Generated from the TEXTINCLUDE 2 resource. 10 | // 11 | #include "winres.h" 12 | 13 | ///////////////////////////////////////////////////////////////////////////// 14 | #undef APSTUDIO_READONLY_SYMBOLS 15 | 16 | ///////////////////////////////////////////////////////////////////////////// 17 | // English (United States) resources 18 | 19 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | 22 | #ifdef APSTUDIO_INVOKED 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // TEXTINCLUDE 26 | // 27 | 28 | 1 TEXTINCLUDE 29 | BEGIN 30 | "resource.h\0" 31 | END 32 | 33 | 2 TEXTINCLUDE 34 | BEGIN 35 | "#include ""winres.h""\r\n" 36 | "\0" 37 | END 38 | 39 | 3 TEXTINCLUDE 40 | BEGIN 41 | "\r\n" 42 | "\0" 43 | END 44 | 45 | #endif // APSTUDIO_INVOKED 46 | 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | // 50 | // Icon 51 | // 52 | 53 | // Icon with lowest ID value placed first to ensure application icon 54 | // remains consistent on all systems. 55 | IDI_APP_ICON ICON "resources\\app_icon.ico" 56 | 57 | 58 | ///////////////////////////////////////////////////////////////////////////// 59 | // 60 | // Version 61 | // 62 | 63 | #ifdef FLUTTER_BUILD_NUMBER 64 | #define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER 65 | #else 66 | #define VERSION_AS_NUMBER 1,0,0 67 | #endif 68 | 69 | #ifdef FLUTTER_BUILD_NAME 70 | #define VERSION_AS_STRING #FLUTTER_BUILD_NAME 71 | #else 72 | #define VERSION_AS_STRING "1.0.0" 73 | #endif 74 | 75 | VS_VERSION_INFO VERSIONINFO 76 | FILEVERSION VERSION_AS_NUMBER 77 | PRODUCTVERSION VERSION_AS_NUMBER 78 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 79 | #ifdef _DEBUG 80 | FILEFLAGS VS_FF_DEBUG 81 | #else 82 | FILEFLAGS 0x0L 83 | #endif 84 | FILEOS VOS__WINDOWS32 85 | FILETYPE VFT_APP 86 | FILESUBTYPE 0x0L 87 | BEGIN 88 | BLOCK "StringFileInfo" 89 | BEGIN 90 | BLOCK "040904e4" 91 | BEGIN 92 | VALUE "CompanyName", "com.devs.help.devs" "\0" 93 | VALUE "FileDescription", "A new Flutter project." "\0" 94 | VALUE "FileVersion", VERSION_AS_STRING "\0" 95 | VALUE "InternalName", "donation_tracker" "\0" 96 | VALUE "LegalCopyright", "Copyright (C) 2021 com.devs.help.devs. All rights reserved." "\0" 97 | VALUE "OriginalFilename", "donation_tracker.exe" "\0" 98 | VALUE "ProductName", "donation_tracker" "\0" 99 | VALUE "ProductVersion", VERSION_AS_STRING "\0" 100 | END 101 | END 102 | BLOCK "VarFileInfo" 103 | BEGIN 104 | VALUE "Translation", 0x409, 1252 105 | END 106 | END 107 | 108 | #endif // English (United States) resources 109 | ///////////////////////////////////////////////////////////////////////////// 110 | 111 | 112 | 113 | #ifndef APSTUDIO_INVOKED 114 | ///////////////////////////////////////////////////////////////////////////// 115 | // 116 | // Generated from the TEXTINCLUDE 3 resource. 117 | // 118 | 119 | 120 | ///////////////////////////////////////////////////////////////////////////// 121 | #endif // not APSTUDIO_INVOKED 122 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.cpp: -------------------------------------------------------------------------------- 1 | #include "flutter_window.h" 2 | 3 | #include 4 | 5 | #include "flutter/generated_plugin_registrant.h" 6 | 7 | FlutterWindow::FlutterWindow(RunLoop* run_loop, 8 | const flutter::DartProject& project) 9 | : run_loop_(run_loop), project_(project) {} 10 | 11 | FlutterWindow::~FlutterWindow() {} 12 | 13 | bool FlutterWindow::OnCreate() { 14 | if (!Win32Window::OnCreate()) { 15 | return false; 16 | } 17 | 18 | RECT frame = GetClientArea(); 19 | 20 | // The size here must match the window dimensions to avoid unnecessary surface 21 | // creation / destruction in the startup path. 22 | flutter_controller_ = std::make_unique( 23 | frame.right - frame.left, frame.bottom - frame.top, project_); 24 | // Ensure that basic setup of the controller was successful. 25 | if (!flutter_controller_->engine() || !flutter_controller_->view()) { 26 | return false; 27 | } 28 | RegisterPlugins(flutter_controller_->engine()); 29 | run_loop_->RegisterFlutterInstance(flutter_controller_->engine()); 30 | SetChildContent(flutter_controller_->view()->GetNativeWindow()); 31 | return true; 32 | } 33 | 34 | void FlutterWindow::OnDestroy() { 35 | if (flutter_controller_) { 36 | run_loop_->UnregisterFlutterInstance(flutter_controller_->engine()); 37 | flutter_controller_ = nullptr; 38 | } 39 | 40 | Win32Window::OnDestroy(); 41 | } 42 | 43 | LRESULT 44 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message, 45 | WPARAM const wparam, 46 | LPARAM const lparam) noexcept { 47 | // Give Flutter, including plugins, an opporutunity to handle window messages. 48 | if (flutter_controller_) { 49 | std::optional result = 50 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, 51 | lparam); 52 | if (result) { 53 | return *result; 54 | } 55 | } 56 | 57 | switch (message) { 58 | case WM_FONTCHANGE: 59 | flutter_controller_->engine()->ReloadSystemFonts(); 60 | break; 61 | } 62 | 63 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam); 64 | } 65 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_FLUTTER_WINDOW_H_ 2 | #define RUNNER_FLUTTER_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "run_loop.h" 10 | #include "win32_window.h" 11 | 12 | // A window that does nothing but host a Flutter view. 13 | class FlutterWindow : public Win32Window { 14 | public: 15 | // Creates a new FlutterWindow driven by the |run_loop|, hosting a 16 | // Flutter view running |project|. 17 | explicit FlutterWindow(RunLoop* run_loop, 18 | const flutter::DartProject& project); 19 | virtual ~FlutterWindow(); 20 | 21 | protected: 22 | // Win32Window: 23 | bool OnCreate() override; 24 | void OnDestroy() override; 25 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, 26 | LPARAM const lparam) noexcept override; 27 | 28 | private: 29 | // The run loop driving events for this window. 30 | RunLoop* run_loop_; 31 | 32 | // The project to run. 33 | flutter::DartProject project_; 34 | 35 | // The Flutter instance hosted by this window. 36 | std::unique_ptr flutter_controller_; 37 | }; 38 | 39 | #endif // RUNNER_FLUTTER_WINDOW_H_ 40 | -------------------------------------------------------------------------------- /windows/runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "flutter_window.h" 6 | #include "run_loop.h" 7 | #include "utils.h" 8 | 9 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, 10 | _In_ wchar_t *command_line, _In_ int show_command) { 11 | // Attach to console when present (e.g., 'flutter run') or create a 12 | // new console when running with a debugger. 13 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { 14 | CreateAndAttachConsole(); 15 | } 16 | 17 | // Initialize COM, so that it is available for use in the library and/or 18 | // plugins. 19 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 20 | 21 | RunLoop run_loop; 22 | 23 | flutter::DartProject project(L"data"); 24 | 25 | std::vector command_line_arguments = 26 | GetCommandLineArguments(); 27 | 28 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); 29 | 30 | FlutterWindow window(&run_loop, project); 31 | Win32Window::Point origin(10, 10); 32 | Win32Window::Size size(1280, 720); 33 | if (!window.CreateAndShow(L"donation_tracker", origin, size)) { 34 | return EXIT_FAILURE; 35 | } 36 | window.SetQuitOnClose(true); 37 | 38 | run_loop.Run(); 39 | 40 | ::CoUninitialize(); 41 | return EXIT_SUCCESS; 42 | } 43 | -------------------------------------------------------------------------------- /windows/runner/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Runner.rc 4 | // 5 | #define IDI_APP_ICON 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devshelpdevs/donation_tracker/15a20005591fc8801d3bc20b0d5fb1151cdb5c28/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /windows/runner/run_loop.cpp: -------------------------------------------------------------------------------- 1 | #include "run_loop.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | RunLoop::RunLoop() {} 8 | 9 | RunLoop::~RunLoop() {} 10 | 11 | void RunLoop::Run() { 12 | MSG msg; 13 | while (GetMessage(&msg, nullptr, 0, 0)) { 14 | TranslateMessage(&msg); 15 | DispatchMessage(&msg); 16 | } 17 | } 18 | void RunLoop::RegisterFlutterInstance( 19 | flutter::FlutterEngine* flutter_instance) { 20 | flutter_instances_.insert(flutter_instance); 21 | } 22 | 23 | void RunLoop::UnregisterFlutterInstance( 24 | flutter::FlutterEngine* flutter_instance) { 25 | flutter_instances_.erase(flutter_instance); 26 | } 27 | 28 | RunLoop::TimePoint RunLoop::ProcessFlutterMessages() { 29 | TimePoint next_event_time = TimePoint::max(); 30 | for (auto instance : flutter_instances_) { 31 | std::chrono::nanoseconds wait_duration = instance->ProcessMessages(); 32 | if (wait_duration != std::chrono::nanoseconds::max()) { 33 | next_event_time = 34 | std::min(next_event_time, TimePoint::clock::now() + wait_duration); 35 | } 36 | } 37 | return next_event_time; 38 | } 39 | -------------------------------------------------------------------------------- /windows/runner/run_loop.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_RUN_LOOP_H_ 2 | #define RUNNER_RUN_LOOP_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | // A runloop that will service events for Flutter instances as well 10 | // as native messages. 11 | class RunLoop { 12 | public: 13 | RunLoop(); 14 | ~RunLoop(); 15 | 16 | // Prevent copying 17 | RunLoop(RunLoop const&) = delete; 18 | RunLoop& operator=(RunLoop const&) = delete; 19 | 20 | // Runs the run loop until the application quits. 21 | void Run(); 22 | 23 | // Registers the given Flutter instance for event servicing. 24 | void RegisterFlutterInstance( 25 | flutter::FlutterEngine* flutter_instance); 26 | 27 | // Unregisters the given Flutter instance from event servicing. 28 | void UnregisterFlutterInstance( 29 | flutter::FlutterEngine* flutter_instance); 30 | 31 | private: 32 | using TimePoint = std::chrono::steady_clock::time_point; 33 | 34 | // Processes all currently pending messages for registered Flutter instances. 35 | TimePoint ProcessFlutterMessages(); 36 | 37 | std::set flutter_instances_; 38 | }; 39 | 40 | #endif // RUNNER_RUN_LOOP_H_ 41 | -------------------------------------------------------------------------------- /windows/runner/runner.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PerMonitorV2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /windows/runner/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | void CreateAndAttachConsole() { 11 | if (::AllocConsole()) { 12 | FILE *unused; 13 | if (freopen_s(&unused, "CONOUT$", "w", stdout)) { 14 | _dup2(_fileno(stdout), 1); 15 | } 16 | if (freopen_s(&unused, "CONOUT$", "w", stderr)) { 17 | _dup2(_fileno(stdout), 2); 18 | } 19 | std::ios::sync_with_stdio(); 20 | FlutterDesktopResyncOutputStreams(); 21 | } 22 | } 23 | 24 | std::vector GetCommandLineArguments() { 25 | // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. 26 | int argc; 27 | wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); 28 | if (argv == nullptr) { 29 | return std::vector(); 30 | } 31 | 32 | std::vector command_line_arguments; 33 | 34 | // Skip the first argument as it's the binary name. 35 | for (int i = 1; i < argc; i++) { 36 | command_line_arguments.push_back(Utf8FromUtf16(argv[i])); 37 | } 38 | 39 | ::LocalFree(argv); 40 | 41 | return command_line_arguments; 42 | } 43 | 44 | std::string Utf8FromUtf16(const wchar_t* utf16_string) { 45 | if (utf16_string == nullptr) { 46 | return std::string(); 47 | } 48 | int target_length = ::WideCharToMultiByte( 49 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 50 | -1, nullptr, 0, nullptr, nullptr); 51 | if (target_length == 0) { 52 | return std::string(); 53 | } 54 | std::string utf8_string; 55 | utf8_string.resize(target_length); 56 | int converted_length = ::WideCharToMultiByte( 57 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 58 | -1, utf8_string.data(), 59 | target_length, nullptr, nullptr); 60 | if (converted_length == 0) { 61 | return std::string(); 62 | } 63 | return utf8_string; 64 | } 65 | -------------------------------------------------------------------------------- /windows/runner/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_UTILS_H_ 2 | #define RUNNER_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Creates a console for the process, and redirects stdout and stderr to 8 | // it for both the runner and the Flutter library. 9 | void CreateAndAttachConsole(); 10 | 11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string 12 | // encoded in UTF-8. Returns an empty std::string on failure. 13 | std::string Utf8FromUtf16(const wchar_t* utf16_string); 14 | 15 | // Gets the command line arguments passed in as a std::vector, 16 | // encoded in UTF-8. Returns an empty std::vector on failure. 17 | std::vector GetCommandLineArguments(); 18 | 19 | #endif // RUNNER_UTILS_H_ 20 | -------------------------------------------------------------------------------- /windows/runner/win32_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_WIN32_WINDOW_H_ 2 | #define RUNNER_WIN32_WINDOW_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | // A class abstraction for a high DPI-aware Win32 Window. Intended to be 11 | // inherited from by classes that wish to specialize with custom 12 | // rendering and input handling 13 | class Win32Window { 14 | public: 15 | struct Point { 16 | unsigned int x; 17 | unsigned int y; 18 | Point(unsigned int x, unsigned int y) : x(x), y(y) {} 19 | }; 20 | 21 | struct Size { 22 | unsigned int width; 23 | unsigned int height; 24 | Size(unsigned int width, unsigned int height) 25 | : width(width), height(height) {} 26 | }; 27 | 28 | Win32Window(); 29 | virtual ~Win32Window(); 30 | 31 | // Creates and shows a win32 window with |title| and position and size using 32 | // |origin| and |size|. New windows are created on the default monitor. Window 33 | // sizes are specified to the OS in physical pixels, hence to ensure a 34 | // consistent size to will treat the width height passed in to this function 35 | // as logical pixels and scale to appropriate for the default monitor. Returns 36 | // true if the window was created successfully. 37 | bool CreateAndShow(const std::wstring& title, 38 | const Point& origin, 39 | const Size& size); 40 | 41 | // Release OS resources associated with window. 42 | void Destroy(); 43 | 44 | // Inserts |content| into the window tree. 45 | void SetChildContent(HWND content); 46 | 47 | // Returns the backing Window handle to enable clients to set icon and other 48 | // window properties. Returns nullptr if the window has been destroyed. 49 | HWND GetHandle(); 50 | 51 | // If true, closing this window will quit the application. 52 | void SetQuitOnClose(bool quit_on_close); 53 | 54 | // Return a RECT representing the bounds of the current client area. 55 | RECT GetClientArea(); 56 | 57 | protected: 58 | // Processes and route salient window messages for mouse handling, 59 | // size change and DPI. Delegates handling of these to member overloads that 60 | // inheriting classes can handle. 61 | virtual LRESULT MessageHandler(HWND window, 62 | UINT const message, 63 | WPARAM const wparam, 64 | LPARAM const lparam) noexcept; 65 | 66 | // Called when CreateAndShow is called, allowing subclass window-related 67 | // setup. Subclasses should return false if setup fails. 68 | virtual bool OnCreate(); 69 | 70 | // Called when Destroy is called. 71 | virtual void OnDestroy(); 72 | 73 | private: 74 | friend class WindowClassRegistrar; 75 | 76 | // OS callback called by message pump. Handles the WM_NCCREATE message which 77 | // is passed when the non-client area is being created and enables automatic 78 | // non-client DPI scaling so that the non-client area automatically 79 | // responsponds to changes in DPI. All other messages are handled by 80 | // MessageHandler. 81 | static LRESULT CALLBACK WndProc(HWND const window, 82 | UINT const message, 83 | WPARAM const wparam, 84 | LPARAM const lparam) noexcept; 85 | 86 | // Retrieves a class instance pointer for |window| 87 | static Win32Window* GetThisFromHandle(HWND const window) noexcept; 88 | 89 | bool quit_on_close_ = false; 90 | 91 | // window handle for top level window. 92 | HWND window_handle_ = nullptr; 93 | 94 | // window handle for hosted content. 95 | HWND child_content_ = nullptr; 96 | }; 97 | 98 | #endif // RUNNER_WIN32_WINDOW_H_ 99 | --------------------------------------------------------------------------------