Commit 3c9bb7db authored by NishanMadush's avatar NishanMadush

Flutter Code

parent 363d0ccf
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled.
version:
revision: 18a827f3933c19f51862dde3fa472197683249d6
channel: stable
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 18a827f3933c19f51862dde3fa472197683249d6
base_revision: 18a827f3933c19f51862dde3fa472197683249d6
- platform: android
create_revision: 18a827f3933c19f51862dde3fa472197683249d6
base_revision: 18a827f3933c19f51862dde3fa472197683249d6
- platform: ios
create_revision: 18a827f3933c19f51862dde3fa472197683249d6
base_revision: 18a827f3933c19f51862dde3fa472197683249d6
- platform: linux
create_revision: 18a827f3933c19f51862dde3fa472197683249d6
base_revision: 18a827f3933c19f51862dde3fa472197683249d6
- platform: macos
create_revision: 18a827f3933c19f51862dde3fa472197683249d6
base_revision: 18a827f3933c19f51862dde3fa472197683249d6
- platform: web
create_revision: 18a827f3933c19f51862dde3fa472197683249d6
base_revision: 18a827f3933c19f51862dde3fa472197683249d6
- platform: windows
create_revision: 18a827f3933c19f51862dde3fa472197683249d6
base_revision: 18a827f3933c19f51862dde3fa472197683249d6
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "bloomerang",
"request": "launch",
"type": "dart"
},
{
"name": "bloomerang (profile mode)",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
},
{
"name": "bloomerang (release mode)",
"request": "launch",
"type": "dart",
"flutterMode": "release"
}
]
}
\ No newline at end of file
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
**/*.keystore
**/*.jks
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.aries.bloomerang"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
minSdkVersion 25
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
implementation platform('com.google.firebase:firebase-bom:30.4.1')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
{
"project_info": {
"project_number": "812696838330",
"firebase_url": "https://plantation-flower-default-rtdb.firebaseio.com",
"project_id": "plantation-flower",
"storage_bucket": "plantation-flower.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:812696838330:android:280379d145581a4080a283",
"android_client_info": {
"package_name": "com.aries.bloomerang"
}
},
"oauth_client": [
{
"client_id": "812696838330-luv2q3v6lolbntagfa3v8lofrrveq0ua.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyCXnGqsBvuJhrycdLHRpXQgi_Oxs3FWywI"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "812696838330-luv2q3v6lolbntagfa3v8lofrrveq0ua.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}
\ No newline at end of file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.aries.bloomerang">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.aries.bloomerang">
<application
android:label="Bloomerang"
android:name="${applicationName}"
android:icon="@mipmap/launcher_icon">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
package com.aries.bloomerang
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.aries.bloomerang">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
buildscript {
ext.kotlin_version = '1.8.22'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.1.2'
classpath 'com.google.gms:google-services:4.3.13'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
</dict>
</plist>
#include "Generated.xcconfig"
#include "Generated.xcconfig"
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.aries.bloomerang;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.aries.bloomerang;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.aries.bloomerang;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
{"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"72x72","expected-size":"72","filename":"72.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"76x76","expected-size":"152","filename":"152.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"50x50","expected-size":"100","filename":"100.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"76x76","expected-size":"76","filename":"76.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"50x50","expected-size":"50","filename":"50.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"72x72","expected-size":"144","filename":"144.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"40x40","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"83.5x83.5","expected-size":"167","filename":"167.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"20x20","expected-size":"20","filename":"20.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"}]}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>950483741203-r767t7704p8536e0sa3qooqh9sihvt8d.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.950483741203-r767t7704p8536e0sa3qooqh9sihvt8d</string>
<key>API_KEY</key>
<string>AIzaSyDRHIH0b_PQ4Bfu_31oF7tpgkO7Tgj-Az0</string>
<key>GCM_SENDER_ID</key>
<string>950483741203</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.aries.bloomerang</string>
<key>PROJECT_ID</key>
<string>fish-tank-7907f</string>
<key>STORAGE_BUCKET</key>
<string>fish-tank-7907f.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:950483741203:ios:1e1e5eb1a8cf63e0cc6de6</string>
<key>DATABASE_URL</key>
<string>https://fish-tank-7907f-default-rtdb.firebaseio.com</string>
</dict>
</plist>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Fishtank</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>fishtank</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>
#import "GeneratedPluginRegistrant.h"
{
"file_generated_by": "FlutterFire CLI",
"purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory",
"GOOGLE_APP_ID": "1:812696838330:ios:da8105f2853dd15d80a283",
"FIREBASE_PROJECT_ID": "plantation-flower",
"GCM_SENDER_ID": "812696838330"
}
\ No newline at end of file
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:bloomerang/Models/FirebaseStructure.dart';
import 'package:bloomerang/Models/User.dart';
import 'package:bloomerang/Views/Auth/Login.dart';
import 'package:flutter/material.dart';
import 'package:bloomerang/Models/Utils.dart';
class AuthController {
static late FirebaseAuth _auth;
late DatabaseReference _databaseRef;
AuthController() {
_auth = FirebaseAuth.instance;
_databaseRef = FirebaseDatabase.instance.ref();
}
Future<bool> doRegistration(data) async {
bool check = true;
await _auth
.createUserWithEmailAndPassword(
email: data['email'],
password: data['password'],
)
.then((value) async {
await _databaseRef
.child(FirebaseStructure.USERS)
.child(value.user!.uid)
.set({
'name': data['name'],
'mobile': data['mobile'],
});
Utils.showToast('Successfully Registered. Please Login Now.');
}).catchError((e) {
check = false;
Utils.showToast(e.toString());
});
return check;
}
Future<bool> doLogin(data) async {
bool check = true;
await _auth
.signInWithEmailAndPassword(
email: data['email'],
password: data['password'],
)
.catchError((e) {
check = false;
late String errorMessage;
switch (e.code) {
case 'invalid-email':
case 'user-not-found':
case 'wrong-password':
errorMessage = 'Invalid credentails.';
break;
case 'user-disabled':
errorMessage = 'Account has been disabled.';
break;
default:
errorMessage = 'Something wrong.';
}
Utils.showToast(errorMessage);
}).then((value) async {
Utils.profileUser = await getUserData();
});
return check;
}
Future<void> logout(context) async {
await _auth.signOut();
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (_) => Login()));
}
Future<ProfileUser> getUserData() async {
late ProfileUser user;
await _databaseRef
.child(FirebaseStructure.USERS)
.child(_auth.currentUser!.uid)
.once()
.then((DatabaseEvent event) async {
Map<dynamic, dynamic> profileUserData = event.snapshot.value as Map;
if (event.snapshot.value != null) {
user = ProfileUser(
name: profileUserData['name'],
email: _auth.currentUser!.email,
mobile: profileUserData['mobile'],
uid: _auth.currentUser!.uid);
}
});
return user;
}
}
import 'package:email_validator/email_validator.dart';
class AuthValidator {
static dynamic validateUsername(String value) {
if (value.isNotEmpty) {
if (!EmailValidator.validate(value)) {
return 'Please check your username.';
}
} else {
return 'Please fill username';
}
}
static dynamic validatePassword(String value) {
if (value.isNotEmpty) {
if (value.length < 8) {
return 'Invalid password (Min : 8 Characters)';
}
} else {
return 'Please fill password';
}
}
static dynamic validateName(String value) {
if (value.isNotEmpty) {
if (value.length < 2) {
return 'Invalid name (Min : 2 Characters)';
}
} else {
return 'Please fill name';
}
}
static dynamic validateNotEmpty(String value) {
if (value.isNotEmpty) {
if (value.length < 2) {
return 'Invalid name (Min : 2 Characters)';
}
} else {
return 'Please fill this field';
}
}
static dynamic validateMobile(String value) {
if (value.isNotEmpty) {
if (value.length != 10) {
return 'Invalid Mobile Number';
}
} else {
return 'Please fill name';
}
}
static dynamic validateRetypePassword(String password, String value) {
if (value.isNotEmpty) {
if (value.length < 8) {
return 'Invalid retype password (Min : 8 Characters)';
} else {
if (password != value) {
return 'Mismatching passwords, Please recheck';
}
}
} else {
return 'Please fill same password';
}
}
}
import 'package:flutter/material.dart';
class UtilColors {
static Color primaryColor = const Color.fromRGBO(53, 128, 13, 1.0);
static Color primaryColorLight = const Color.fromRGBO(235, 64, 119, 1.0);
static Color secondaryColor = const Color.fromARGB(255, 90, 108, 86);
static Color secondaryColorLight = const Color.fromARGB(255, 121, 138, 118);
static Color whiteColor = const Color.fromRGBO(250, 250, 250, 1.0);
static Color whiteColorLight = const Color.fromRGBO(255, 255, 255, 1.0);
static Color blackColor = const Color.fromRGBO(33, 33, 33, 1.0);
static Color greyColorLight = const Color.fromRGBO(245, 245, 245, 1.0);
static Color greyColor = const Color.fromRGBO(158, 158, 158, 1.0);
static Color greyColorDark = const Color.fromRGBO(97, 97, 97, 1.0);
static Color primaryStatusBarColor = const Color.fromRGBO(0, 0, 0, 1);
static Color redColor = const Color.fromRGBO(198, 40, 40, 1);
static Color greenColor = const Color.fromRGBO(76, 175, 80, 1);
static Color blueColor = const Color.fromRGBO(21, 101, 192, 1);
static Color purpleColor = const Color.fromRGBO(106, 27, 154, 1);
static Color orangeColor = const Color.fromRGBO(239, 108, 0, 1);
static Color orangeDarkColor = const Color.fromRGBO(230, 81, 0, 1);
static Color yellowColor = const Color.fromRGBO(245, 124, 0, 1);
}
class FirebaseStructure {
static const USERS = 'users';
static const LIVEDATA = 'live_data';
static const FLOWERBUDSCOUNT = 'flower_budscount';
static const FlowerFreshness = 'flower_freshness';
static const FLOWERDISEASE = 'flower_disease';
static const DISEASES = 'diseases';
static const HISTORY = 'history';
static const NOTIFICATION = 'notification';
}
class UtilImages {
static var logoPNG = 'assets/img/logo.png';
static var bgPNG = 'assets/img/bg.png';
static var userPNG = 'assets/img/user_sample.png';
static var medicalcentre = 'assets/img/marker.png';
}
class UtilStrings {
static var splashScreen = 'Developed by Your Name.';
static var appTitle = 'Bloomerang';
static var appTitleSection1 = 'Bloomerang';
static var appTitleSection2 = '';
static var appSubtitle = 'watch your Bloomerang';
static var loginSubTitle = 'Unlock your account with credentails';
static var registrationSubTitle = 'Create your bloomerang account';
static var emptyList = 'No Records Found.';
static var forgetPasswordSubTitle = 'Forget Password';
}
class ProfileUser {
var uid, name, mobile, email;
ProfileUser({this.uid, this.name, this.mobile, this.email});
}
import 'dart:convert';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:bloomerang/Models/User.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:bloomerang/Models/Colors.dart';
import 'package:bloomerang/Models/Strings.dart';
import 'package:bloomerang/Views/Widgets/PopUps/PopUpLoading.dart';
import 'package:intl/intl.dart';
class Utils {
//Fonts Start
static double smallFonts = 10.0;
static double xlFonts = 30.0;
//Fonts End
static String googleMapsKey = 'AIzaSyD8HZ9Is3SwaYwv9WiTvWZIKwVH15M8Dbw';
static String apiUrl = 'http://192.168.1.170:8003/request/';
static late Size displaySize;
static var loadingMessage;
static late ProfileUser profileUser;
static late String loggedBus;
static String getCurrentDate() {
return DateFormat("yyyy/MM/dd").format(DateTime.now());
}
static String formatDate(DateTime date) {
return DateFormat("yyyy/MM/dd").format(date);
}
static String formatTime(DateTime date) {
return DateFormat("hh:mm a").format(date);
}
static String formatDateTime(DateTime date) {
return DateFormat("yyyy/MM/dd hh:mm a").format(date);
}
static String formatTimeAPI(DateTime date) {
return DateFormat("hh:mm:ss").format(date);
}
static var lightNavbar = SystemUiOverlayStyle.light.copyWith(
statusBarBrightness: Brightness.light,
systemNavigationBarColor: UtilColors.blackColor,
statusBarColor: UtilColors.primaryStatusBarColor);
static var darkNavbar = SystemUiOverlayStyle.dark.copyWith(
statusBarBrightness: Brightness.light,
systemNavigationBarColor: UtilColors.blackColor,
statusBarColor: UtilColors.primaryStatusBarColor);
//TextStyles
static TextStyle getprimaryStyle(Color color) {
return GoogleFonts.nunitoSans(color: color);
}
static TextStyle getprimaryStyleSmall(Color color) {
return GoogleFonts.nunitoSans(color: color, fontSize: 13.0);
}
static TextStyle getprimaryBoldStyle(Color color) {
return GoogleFonts.nunitoSans(color: color, fontWeight: FontWeight.bold);
}
static TextStyle getprimaryFieldTextStyle(Color color) {
return GoogleFonts.nunitoSans(color: UtilColors.blackColor, fontSize: 13.0);
}
static TextStyle getprimaryFieldTextStylePopUp(Color color) {
return GoogleFonts.nunitoSans(
color: UtilColors.primaryColor, fontSize: 13.0);
}
//TextFormField Styles
static double borderRadius = 5.0;
static double buttonBorderRadius = 5.0;
static InputDecoration getDefaultTextInputDecoration(
String label, Icon suffixIcon) {
return InputDecoration(
labelText: label,
errorStyle: TextStyle(fontSize: 11, color: Colors.red),
contentPadding: EdgeInsets.symmetric(horizontal: 12.0, vertical: 10.0),
labelStyle: TextStyle(fontSize: 13.0, color: UtilColors.greyColor),
suffixIcon: suffixIcon,
fillColor: Colors.white,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(borderRadius),
borderSide: BorderSide(),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(borderRadius),
borderSide: BorderSide(color: UtilColors.secondaryColor, width: 1),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(borderRadius),
borderSide: BorderSide(color: UtilColors.primaryColor, width: 1),
));
}
static InputDecoration getDefaultDropDownInputDecoration(
String label, Icon suffixIcon) {
return InputDecoration(
errorStyle: TextStyle(fontSize: 11, color: Colors.red),
labelStyle: TextStyle(fontSize: 13.0, color: UtilColors.greyColor),
suffixIcon: suffixIcon,
fillColor: Colors.white,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(borderRadius),
borderSide: BorderSide(),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(borderRadius),
borderSide: BorderSide(color: UtilColors.secondaryColor, width: 1),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(borderRadius),
borderSide: BorderSide(color: UtilColors.primaryColor, width: 1),
));
}
//Loading Widgets
static bool checkShowLoader = false;
static late BuildContext parentLoadingContext;
static Widget getListLoader() {
return Wrap(
children: const [
Padding(
padding: EdgeInsets.only(top: 50.0),
child: CircularProgressIndicator(),
)
],
);
}
static Widget getEmptyList() {
return Center(
child: AutoSizeText(
UtilStrings.emptyList,
style: GoogleFonts.nunitoSans(
fontSize: 15.0, color: UtilColors.blackColor),
),
);
}
static Future showLoader(context) async {
await showDialog(
context: context,
builder: (_) => PopUpLoading(),
).then((onValue) {
parentLoadingContext = context;
checkShowLoader = true;
});
}
static Future showConfirmation(
context,
) async {
await showDialog(
context: context,
builder: (_) => PopUpLoading(),
).then((onValue) {
parentLoadingContext = context;
checkShowLoader = true;
});
}
static Future showLoaderWithCustomMessage(context, message) async {
Utils.loadingMessage = message;
await showDialog(
context: context,
builder: (_) => PopUpLoading(),
).then((onValue) {
parentLoadingContext = context;
checkShowLoader = true;
});
}
static Future hideLoader() async {
if (checkShowLoader == true && parentLoadingContext != null) {
Navigator.pop(parentLoadingContext);
checkShowLoader = false;
Utils.loadingMessage = null;
}
}
static Future hideLoaderCurrrent(context) async {
Navigator.pop(context);
checkShowLoader = false;
}
//Toast Contents
static showToast(String message) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: Colors.black,
textColor: Colors.white,
fontSize: 14.0);
}
static getGradientBackground() {
return BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
tileMode: TileMode.decal,
end: Alignment.bottomLeft,
colors: [
UtilColors.primaryColor,
UtilColors.secondaryColor,
],
));
}
static getTextGradient() {
return LinearGradient(
colors: <Color>[UtilColors.primaryColor, UtilColors.primaryColorLight],
).createShader(Rect.fromLTWH(0.0, 0.0, 200.0, 70.0));
}
}
import 'package:email_validator/email_validator.dart';
class AuthValidator {
static dynamic validateUsername(String value) {
if (value.isNotEmpty) {
if (!EmailValidator.validate(value)) {
return 'Please check your username.';
}
} else {
return 'Please fill username';
}
}
static dynamic validatePassword(String value) {
if (value.isNotEmpty) {
if (value.length < 8) {
return 'Invalid password (Min : 8 Characters)';
}
} else {
return 'Please fill password';
}
}
static dynamic validateName(String value) {
if (value.isNotEmpty) {
if (value.length < 2) {
return 'Invalid name (Min : 2 Characters)';
}
} else {
return 'Please fill name';
}
}
static dynamic validateMobile(String value) {
if (value.isNotEmpty) {
if (value.length != 10) {
return 'Invalid Mobile Number';
}
} else {
return 'Please fill name';
}
}
static dynamic validateRetypePassword(String password, String value) {
if (value.isNotEmpty) {
if (value.length < 8) {
return 'Invalid retype password (Min : 8 Characters)';
} else {
if (password != value) {
return 'Mismatching passwords, Please recheck';
}
}
} else {
return 'Please fill same password';
}
}
}
class UtilVideos{
static var logo = 'assets/videos/login.mp4';
}
\ No newline at end of file
import 'package:bloomerang/Controllers/AuthController.dart';
import 'package:bloomerang/Controllers/AuthValidator.dart';
import 'package:bloomerang/Models/Videos.dart';
import 'package:bloomerang/Views/Home/Home.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:bloomerang/Models/Colors.dart';
import 'package:bloomerang/Models/Images.dart';
import 'package:bloomerang/Models/Strings.dart';
import 'package:bloomerang/Models/Utils.dart';
import 'package:bloomerang/Views/Auth/Register.dart';
import 'package:video_player/video_player.dart';
class Login extends StatefulWidget {
Login({Key? key}) : super(key: key);
@override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
final TextEditingController _email = TextEditingController();
final TextEditingController _password = TextEditingController();
final _loginFormKey = GlobalKey<FormState>();
bool _rememberMe = false;
bool _obscurePassword = true;
late AuthController _authController;
late VideoPlayerController _controller;
@override
void initState() {
super.initState();
SystemChrome.setSystemUIOverlayStyle(Utils.lightNavbar);
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
_email.text = 'user@gmail.com';
_password.text = 'User@123';
initializeVideoBackground();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
double spaceAround = 35.0;
double fieldspaces = 30.0;
double fieldspacesmid = 30.0;
double fontsize = 14;
_authController = AuthController();
return SafeArea(
child: Scaffold(
backgroundColor: UtilColors.greyColor,
body: Container(
alignment: Alignment.center,
child: SingleChildScrollView(
child: Stack(
children: [
Positioned(
child: SizedBox(
height: Utils.displaySize.height,
width: Utils.displaySize.width,
child: (_controller.value.isInitialized)
? AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
)
: Image.asset(
UtilImages.bgPNG,
fit: BoxFit.fitHeight,
),
)),
SizedBox(
width: Utils.displaySize.width,
height: Utils.displaySize.height,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Visibility(
visible:
(Utils.displaySize.height < 1000) ? false : true,
child: Container(
padding: EdgeInsets.only(bottom: spaceAround),
width: Utils.displaySize.width * 0.35,
child: SizedBox(
child: Image.asset(UtilImages.logoPNG),
),
)),
Container(
decoration: BoxDecoration(
color: UtilColors.whiteColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0))),
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Form(
key: _loginFormKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: fieldspaces,
),
SizedBox(
width: Utils.displaySize.width * 0.25,
child: Image.asset(UtilImages.logoPNG),
),
SizedBox(
height: fieldspaces,
),
Align(
alignment: Alignment.topCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(UtilStrings.appTitleSection1,
style: TextStyle(
fontSize: 23.0,
color: UtilColors.primaryColor)),
],
),
),
Align(
alignment: Alignment.topCenter,
child: Padding(
padding: const EdgeInsets.only(
top: 10.0, bottom: 10.0),
child: Text(
UtilStrings.loginSubTitle,
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w400,
foreground: Paint()
..shader = Utils.getTextGradient()),
),
),
),
const Divider(),
SizedBox(
height: fieldspacesmid,
),
TextFormField(
controller: _email,
decoration:
Utils.getDefaultTextInputDecoration(
'Email',
Icon(
Icons.email,
color: UtilColors.greyColor
.withOpacity(0.6),
)),
cursorColor: UtilColors.primaryColor,
keyboardType: TextInputType.text,
style: Utils.getprimaryFieldTextStyle(
UtilColors.blackColor),
validator: (value) {
return AuthValidator.validateUsername(
value!);
},
),
SizedBox(
height: fieldspacesmid,
),
TextFormField(
controller: _password,
decoration:
Utils.getDefaultTextInputDecoration(
'Password',
Icon(Icons.lock,
color: UtilColors.greyColor
.withOpacity(0.6))),
cursorColor: UtilColors.primaryColor,
obscureText: _obscurePassword,
keyboardType: TextInputType.emailAddress,
style: Utils.getprimaryFieldTextStyle(
UtilColors.blackColor),
validator: (value) {
return AuthValidator.validatePassword(
value!);
},
onChanged: (value) {
setState(() {
_obscurePassword = true;
});
},
),
SizedBox(
height: fieldspaces,
),
Row(
children: [
SizedBox(
height: 24.0,
width: 24.0,
child: Checkbox(
value: _rememberMe,
onChanged: (val) {
setState(() {
_rememberMe = val!;
});
},
activeColor: UtilColors.primaryColor,
focusColor: Colors.red,
checkColor: UtilColors.whiteColor,
hoverColor: Colors.red,
tristate: false,
),
),
Padding(
padding:
const EdgeInsets.only(left: 10.0),
child: GestureDetector(
onTap: () {
setState(() {
_rememberMe = !_rememberMe;
});
},
child: Text(
'Remember Password',
style: TextStyle(fontSize: fontsize),
),
),
)
],
),
SizedBox(
height: fieldspaces,
),
SizedBox(
width: double.infinity,
height: 50.0,
child: TextButton(
style: ButtonStyle(
foregroundColor:
MaterialStateProperty.all<Color>(
UtilColors.whiteColor),
backgroundColor:
MaterialStateProperty.all<Color>(
UtilColors.primaryColor),
),
onPressed: () async {
if (_loginFormKey.currentState!
.validate()) {
FocusScope.of(context).unfocus();
Utils.showLoader(context);
try {
await _authController.doLogin({
'email': _email.text,
'password': _password.text
}).then((value) {
if (value == true) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) =>
const Home()));
}
});
} catch (e) {
Utils.hideLoaderCurrrent(context);
}
}
},
child: Text(
"Let's Start",
style: GoogleFonts.nunitoSans(),
),
),
),
SizedBox(
height: spaceAround,
),
Align(
alignment: Alignment.topCenter,
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => Register()));
},
child: Text(
'No account yet, register today !',
style: TextStyle(fontSize: fontsize),
),
),
),
SizedBox(
height: fieldspaces,
),
],
)),
),
),
],
),
)
],
),
),
),
));
}
void initializeVideoBackground() {
_controller = VideoPlayerController.asset(UtilVideos.logo)
..initialize().then((_) {
setState(() {
_controller.setVolume(0.0);
_controller.setLooping(true);
_controller.play();
});
});
}
}
import 'package:bloomerang/Controllers/AuthController.dart';
import 'package:bloomerang/Controllers/AuthValidator.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:bloomerang/Models/Colors.dart';
import 'package:bloomerang/Models/Strings.dart';
import 'package:bloomerang/Models/Utils.dart';
class RecoverPassword extends StatefulWidget {
const RecoverPassword({Key? key}) : super(key: key);
@override
_RecoverPasswordState createState() => _RecoverPasswordState();
}
class _RecoverPasswordState extends State<RecoverPassword> {
TextEditingController _email = TextEditingController();
final _formKey = GlobalKey<FormState>();
late AuthController _authController;
@override
void initState() {
super.initState();
SystemChrome.setSystemUIOverlayStyle(Utils.lightNavbar);
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
}
@override
Widget build(BuildContext context) {
double spaceAround = 10.0;
double fieldspaces = 15.0;
double fieldspacesmid = 20.0;
_authController = AuthController();
return SafeArea(
child: Scaffold(
backgroundColor: UtilColors.greyColor,
body: Container(
alignment: Alignment.center,
child: SingleChildScrollView(
child: Container(
child: Stack(
children: [
Container(
width: Utils.displaySize.width,
height: Utils.displaySize.height,
decoration: Utils.getGradientBackground(),
),
Container(
width: Utils.displaySize.width,
height: Utils.displaySize.height,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.symmetric(
horizontal: spaceAround, vertical: spaceAround),
child: Card(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: fieldspaces,
),
Align(
alignment: Alignment.topCenter,
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text(
UtilStrings.appTitleSection1
.toUpperCase(),
style: TextStyle(
fontSize: 23.0,
color:
UtilColors.primaryColor)),
Padding(
padding: EdgeInsets.only(left: 5.0),
child: Text(
UtilStrings.appTitleSection2
.toUpperCase(),
style: TextStyle(
fontSize: 23.0,
color: UtilColors
.secondaryColor)),
)
],
),
),
Align(
alignment: Alignment.topCenter,
child: Padding(
padding: EdgeInsets.only(
top: 5.0, bottom: 10.0),
child: Text(
UtilStrings.forgetPasswordSubTitle
.toUpperCase(),
style: TextStyle(
fontSize: 11.0,
fontWeight: FontWeight.w600,
foreground: Paint()
..shader =
Utils.getTextGradient()),
),
),
),
Divider(),
SizedBox(
height: fieldspacesmid,
),
TextFormField(
controller: _email,
decoration:
Utils.getDefaultTextInputDecoration(
'Your Email',
Icon(
Icons.email,
color: UtilColors.greyColor
.withOpacity(0.6),
)),
cursorColor: UtilColors.primaryColor,
keyboardType: TextInputType.emailAddress,
style: Utils.getprimaryFieldTextStyle(
UtilColors.greyColor),
validator: (value) {
return AuthValidator.validateUsername(
value!);
},
),
SizedBox(
height: fieldspaces,
),
SizedBox(
child: TextButton(
onPressed: () async {
// if (_formKey.currentState!
// .validate()) {
// _authController
// .sendRecoverLink(_email.text);
// }
},
style: TextButton.styleFrom(
backgroundColor: UtilColors
.whiteColorLight,
side: BorderSide(
color:
UtilColors.primaryColor,
width: 1),
shape:
const BeveledRectangleBorder(
borderRadius:
BorderRadius.all(
Radius.circular(
5))),
primary:
UtilColors.primaryColorLight),
child: Text(
"SEND RECOVER EMAIL.",
style: TextStyle(
color: UtilColors.primaryColor),
)),
width: Utils.displaySize.width,
),
SizedBox(
height: fieldspaces,
),
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: const Text(
"Back to login",
style: TextStyle(fontSize: 12.0),
),
),
SizedBox(
height: fieldspaces,
),
],
)),
),
),
),
],
),
)
],
),
),
),
),
));
}
}
import 'package:bloomerang/Controllers/AuthController.dart';
import 'package:bloomerang/Controllers/AuthValidator.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:bloomerang/Models/Colors.dart';
import 'package:bloomerang/Models/Images.dart';
import 'package:bloomerang/Models/Strings.dart';
import 'package:bloomerang/Models/Utils.dart';
import 'package:google_fonts/google_fonts.dart';
class Register extends StatefulWidget {
const Register({Key? key}) : super(key: key);
@override
_RegisterState createState() => _RegisterState();
}
class _RegisterState extends State<Register> {
final TextEditingController _name = TextEditingController();
final TextEditingController _mobile = TextEditingController();
final TextEditingController _email = TextEditingController();
final TextEditingController _password = TextEditingController();
final TextEditingController _repassword = TextEditingController();
final _registerFormKey = GlobalKey<FormState>();
bool _obscurePassword1 = true;
bool _obscurePassword2 = true;
final AuthController _authController = AuthController();
@override
void initState() {
super.initState();
SystemChrome.setSystemUIOverlayStyle(Utils.lightNavbar);
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
}
@override
Widget build(BuildContext context) {
double fieldspaces = 35.0;
double fieldspacesmid = (Utils.displaySize.height < 1000) ? 15 : 25;
double fontsize = 14;
return SafeArea(
child: Scaffold(
backgroundColor: UtilColors.greyColor,
body: Container(
alignment: Alignment.center,
child: SingleChildScrollView(
child: SizedBox(
child: Stack(
children: [
Positioned(
child: SizedBox(
height: Utils.displaySize.height,
width: Utils.displaySize.width,
child: Image.asset(
UtilImages.bgPNG,
fit: BoxFit.fitHeight,
),
)),
SizedBox(
width: Utils.displaySize.width,
height: Utils.displaySize.height,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
decoration: BoxDecoration(
color: UtilColors.whiteColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0))),
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Form(
key: _registerFormKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: fieldspaces,
),
Align(
alignment: Alignment.topCenter,
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text(UtilStrings.appTitleSection1,
style: TextStyle(
fontSize: 23.0,
color:
UtilColors.primaryColor)),
Padding(
padding:
const EdgeInsets.only(left: 5.0),
child: Text(
UtilStrings.appTitleSection2
.toUpperCase(),
style: TextStyle(
fontSize: 23.0,
color: UtilColors
.secondaryColor)),
)
],
),
),
Align(
alignment: Alignment.topCenter,
child: Padding(
padding: const EdgeInsets.only(
top: 10.0, bottom: 10.0),
child: Text(
UtilStrings.registrationSubTitle,
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w400,
foreground: Paint()
..shader =
Utils.getTextGradient()),
),
),
),
const Divider(),
SizedBox(
height: fieldspacesmid,
),
Padding(
padding:
const EdgeInsets.only(bottom: 20.0),
child: TextFormField(
controller: _name,
decoration:
Utils.getDefaultTextInputDecoration(
'Name',
Icon(
Icons.person,
color: UtilColors.greyColor
.withOpacity(0.6),
)),
cursorColor: UtilColors.primaryColor,
keyboardType: TextInputType.name,
style: Utils.getprimaryFieldTextStyle(
UtilColors.greyColor),
validator: (value) {
return AuthValidator.validateName(
value!);
},
),
),
Padding(
padding:
const EdgeInsets.only(bottom: 20.0),
child: TextFormField(
controller: _mobile,
decoration:
Utils.getDefaultTextInputDecoration(
'Mobile Number',
Icon(
Icons.send_to_mobile,
color: UtilColors.greyColor
.withOpacity(0.6),
)),
cursorColor: UtilColors.primaryColor,
keyboardType: TextInputType.number,
style: Utils.getprimaryFieldTextStyle(
UtilColors.greyColor),
validator: (value) {
return AuthValidator.validateMobile(
value!);
},
),
),
Padding(
padding:
const EdgeInsets.only(bottom: 20.0),
child: TextFormField(
controller: _email,
decoration:
Utils.getDefaultTextInputDecoration(
'Email',
Icon(
Icons.email,
color: UtilColors.greyColor
.withOpacity(0.6),
)),
cursorColor: UtilColors.primaryColor,
keyboardType: TextInputType.emailAddress,
style: Utils.getprimaryFieldTextStyle(
UtilColors.greyColor),
validator: (value) {
return AuthValidator.validateUsername(
value!);
},
),
),
Padding(
padding:
const EdgeInsets.only(bottom: 20.0),
child: TextFormField(
controller: _password,
decoration:
Utils.getDefaultTextInputDecoration(
'Password',
Icon(Icons.lock,
color: UtilColors.greyColor
.withOpacity(0.6))),
cursorColor: UtilColors.primaryColor,
obscureText: _obscurePassword1,
keyboardType: TextInputType.text,
style: Utils.getprimaryFieldTextStyle(
UtilColors.blackColor),
validator: (value) {
return AuthValidator.validatePassword(
value!);
},
onChanged: (value) {
setState(() {
_obscurePassword1 = true;
});
},
),
),
TextFormField(
controller: _repassword,
decoration:
Utils.getDefaultTextInputDecoration(
'Retype Password',
Icon(Icons.lock,
color: UtilColors.greyColor
.withOpacity(0.6))),
cursorColor: UtilColors.primaryColor,
obscureText: _obscurePassword2,
keyboardType: TextInputType.text,
style: Utils.getprimaryFieldTextStyle(
UtilColors.blackColor),
validator: (value) {
return AuthValidator
.validateRetypePassword(
_password.text, value!);
},
onChanged: (value) {
setState(() {
_obscurePassword2 = true;
});
},
),
SizedBox(
height: fieldspaces,
),
SizedBox(
width: double.infinity,
height: 50.0,
child: TextButton(
style: ButtonStyle(
foregroundColor:
MaterialStateProperty.all<Color>(
UtilColors.whiteColor),
backgroundColor:
MaterialStateProperty.all<Color>(
UtilColors.primaryColor),
),
onPressed: () async {
if (_registerFormKey.currentState!
.validate()) {
FocusScope.of(context).unfocus();
Utils.showLoader(context);
await _authController
.doRegistration({
'name': _name.text.toString(),
'mobile': _mobile.text.toString(),
'email': _email.text.toString(),
'type': 2,
'password':
_password.text.toString(),
}).then((value) =>
Utils.hideLoaderCurrrent(
context));
_registerFormKey.currentState!
.reset();
_name.text = '';
_mobile.text = '';
_email.text = '';
_password.text = '';
_repassword.text = '';
}
},
child: Text(
"Register",
style: GoogleFonts.nunitoSans(),
),
)),
const SizedBox(
height: 20.0,
),
Align(
alignment: Alignment.topCenter,
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Text(
'Already have an account, Login now !',
style: TextStyle(fontSize: fontsize),
),
),
),
SizedBox(
height: fieldspaces,
),
],
)),
),
),
],
),
)
],
),
),
),
),
));
}
}
import 'dart:async';
import 'package:bloomerang/Models/Colors.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:bloomerang/Models/Images.dart';
import 'package:bloomerang/Models/Strings.dart';
import 'package:bloomerang/Models/Utils.dart';
import 'package:bloomerang/Views/Auth/Login.dart';
class SplashScreen extends StatefulWidget {
const SplashScreen({Key? key}) : super(key: key);
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
late Timer _timer;
@override
void initState() {
super.initState();
startApp();
}
@override
void dispose() {
_timer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
Utils.displaySize = MediaQuery.of(context).size;
return SafeArea(
child: Scaffold(
body: Container(
color: UtilColors.whiteColor ,
child: Stack(
children: [
Align(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
height: Utils.displaySize.width * 0.3,
width: Utils.displaySize.width * 0.5,
child: Image.asset(UtilImages.logoPNG),
),
Text(
UtilStrings.appTitle,
style: GoogleFonts.nunitoSans(
color: UtilColors.primaryColor,
fontWeight: FontWeight.w500,
fontSize: 35.0),
),
Text(
UtilStrings.appSubtitle.toUpperCase(),
style: GoogleFonts.nunitoSans(
color: UtilColors.secondaryColor,
fontWeight: FontWeight.w500,
fontSize: 12.0,
),
),
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: Text(
UtilStrings.splashScreen,
style: GoogleFonts.nunitoSans(
color: UtilColors.blackColor,
fontWeight: FontWeight.w500,
fontSize: 14.0),
),
),
)
],
),
),
));
}
void startApp() async {
_timer = Timer.periodic(
const Duration(seconds: 3),
(t) => Navigator.of(context, rootNavigator: true).pushReplacement(
MaterialPageRoute(builder: (_) => Login()),
));
}
}
import 'dart:convert';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:bloomerang/Controllers/AuthValidator.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:bloomerang/Models/FirebaseStructure.dart';
import 'package:bloomerang/Views/Home/HomeDrawer.dart';
import 'package:bloomerang/Views/Widgets/custom_date_selector.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:bloomerang/Models/Colors.dart';
import 'package:bloomerang/Models/Utils.dart';
import 'package:intl/intl.dart';
class Diseases extends StatefulWidget {
const Diseases({Key? key}) : super(key: key);
@override
_DiseasesState createState() => _DiseasesState();
}
class _DiseasesState extends State<Diseases> {
final _scaffoldKey = GlobalKey<ScaffoldState>();
final double topSpace = Utils.displaySize.width * 0.4;
final DatabaseReference _databaseReference = FirebaseDatabase.instance.ref();
List<dynamic> list = [];
DateTime start = DateTime.now();
DateTime end = DateTime.now();
bool useFilters = false;
@override
void initState() {
getData();
super.initState();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
key: _scaffoldKey,
drawer: Drawer(
child: HomeDrawer(
selection: 1,
),
),
backgroundColor: UtilColors.whiteColor,
body: SizedBox(
width: Utils.displaySize.width,
height: Utils.displaySize.height,
child: Column(
children: [
Expanded(
flex: 0,
child: Container(
decoration: BoxDecoration(color: UtilColors.primaryColor),
child: Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0, top: 18.0, bottom: 18.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(
Icons.arrow_left,
color: UtilColors.whiteColor,
),
),
AutoSizeText(
"Diseases",
style: GoogleFonts.nunitoSans(
fontSize: 18.0, color: UtilColors.whiteColor),
),
GestureDetector(
onTap: () async {
showEnrollment(null, null);
},
child: Icon(
Icons.add,
color: UtilColors.whiteColor,
),
),
],
),
),
)),
const SizedBox(
height: 10.0,
),
Expanded(
flex: 1,
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: UtilColors.whiteColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0))),
child: Padding(
padding: const EdgeInsets.all(5.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
for (var rec in list)
Padding(
padding:
const EdgeInsets.symmetric(vertical: 5.0),
child: Card(
child: ListTile(
title: Text(
rec['value']['disease'],
style: GoogleFonts.nunitoSans(
color: UtilColors.primaryColor,
fontSize: 12.0),
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
onTap: () => showEnrollment(
rec['key'], rec['value']),
child: Icon(Icons.edit,
color: UtilColors.yellowColor),
),
Padding(
padding: const EdgeInsets.only(
left: 20.0),
child: GestureDetector(
onTap: () {
_databaseReference
.child(FirebaseStructure
.DISEASES)
.child(rec['key'])
.remove()
.then((value) => getData());
},
child: Icon(Icons.delete,
color: UtilColors.redColor),
),
)
],
),
),
),
)
]),
),
),
))
],
)),
));
}
Future<void> getData() async {
_databaseReference
.child(FirebaseStructure.DISEASES)
.once()
.then((DatabaseEvent data) {
list.clear();
for (DataSnapshot element in data.snapshot.children) {
list.add({'key': element.key, 'value': element.value});
}
setState(() {});
});
}
String getDateTime(int mills) {
return DateFormat('yyyy/MM/dd hh:mm a')
.format(DateTime.fromMillisecondsSinceEpoch(mills));
}
Uint8List getImageString(String value) {
return Uri.parse(value).data!.contentAsBytes();
}
final _formKey = GlobalKey<FormState>();
void showEnrollment(key, dynamic savedRecord) {
TextEditingController _disease = TextEditingController();
TextEditingController _description = TextEditingController();
TextEditingController _solution = TextEditingController();
if (savedRecord != null) {
_disease.text = savedRecord['disease'];
_description.text = savedRecord['description'];
_solution.text = savedRecord['solution'];
}
showModalBottomSheet<void>(
context: context,
isScrollControlled: true,
builder: (BuildContext context) {
return SizedBox(
width: Utils.displaySize.width,
height: Utils.displaySize.height*0.7,
child: Column(
children: [
Expanded(
flex: 0,
child: Container(
decoration:
BoxDecoration(color: UtilColors.primaryColor),
child: Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0, top: 18.0, bottom: 18.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
Icons.refresh,
color: UtilColors.primaryColor,
),
AutoSizeText(
"Enrollment",
style: GoogleFonts.nunitoSans(
fontSize: 18.0,
color: UtilColors.whiteColor),
),
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(
Icons.close,
color: UtilColors.whiteColor,
),
),
],
),
),
)),
Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Form(
key: _formKey,
child: Wrap(
children: [
Padding(
padding: const EdgeInsets.only(
bottom: 10.0, top: 20.0),
child: TextFormField(
controller: _disease,
decoration: Utils.getDefaultTextInputDecoration(
'Disease Name (Please do not duplicate)',
Icon(
Icons.coronavirus,
color:
UtilColors.greyColor.withOpacity(0.6),
)),
cursorColor: UtilColors.primaryColor,
keyboardType: TextInputType.text,
style: Utils.getprimaryFieldTextStyle(
UtilColors.blackColor),
validator: (value) {
return AuthValidator.validateNotEmpty(value!);
},
),
),
Padding(
padding: const EdgeInsets.only(
bottom: 10.0, top: 10.0),
child: TextFormField(
controller: _description,
decoration: Utils.getDefaultTextInputDecoration(
'Description',
Icon(
Icons.medical_information,
color:
UtilColors.greyColor.withOpacity(0.6),
)),
cursorColor: UtilColors.primaryColor,
maxLines: 5,
keyboardType: TextInputType.multiline,
style: Utils.getprimaryFieldTextStyle(
UtilColors.blackColor),
validator: (value) {
return AuthValidator.validateNotEmpty(value!);
},
),
),
Padding(
padding: const EdgeInsets.only(
bottom: 10.0, top: 10.0),
child: TextFormField(
controller: _solution,
decoration: Utils.getDefaultTextInputDecoration(
'Solution',
Icon(
Icons.category,
color:
UtilColors.greyColor.withOpacity(0.6),
)),
cursorColor: UtilColors.primaryColor,
maxLines: 5,
keyboardType: TextInputType.multiline,
style: Utils.getprimaryFieldTextStyle(
UtilColors.blackColor),
validator: (value) {
return AuthValidator.validateNotEmpty(value!);
},
),
),
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: SizedBox(
width: double.infinity,
height: 50.0,
child: TextButton(
style: ButtonStyle(
foregroundColor:
MaterialStateProperty.all<Color>(
UtilColors.whiteColor),
backgroundColor:
MaterialStateProperty.all<Color>(
UtilColors.primaryColor),
),
onPressed: () async {
if (_formKey.currentState!.validate()) {
FocusScope.of(context).unfocus();
Utils.showLoader(context);
DatabaseReference ref = _databaseReference
.child(FirebaseStructure.DISEASES)
.child(((savedRecord != null)
? key
: _disease.text
.toLowerCase()
.replaceAll(' ', '')));
ref.set({
'disease': _disease.text,
'description': _description.text,
'solution': _solution.text,
}).then((value) {
getData();
Utils.hideLoaderCurrrent(context);
Navigator.pop(context);
});
}
},
child: Text(
(savedRecord != null) ? "Update" : "Save",
style: GoogleFonts.nunitoSans(),
),
),
),
),
],
)),
))
],
));
});
}
}
import 'dart:convert';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:bloomerang/Models/FirebaseStructure.dart';
import 'package:bloomerang/Views/Home/HomeDrawer.dart';
import 'package:bloomerang/Views/Widgets/GraphView.dart';
import 'package:bloomerang/Views/Widgets/custom_date_selector.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:bloomerang/Models/Colors.dart';
import 'package:bloomerang/Models/Utils.dart';
import 'package:intl/intl.dart';
class FlowerBudsCount extends StatefulWidget {
const FlowerBudsCount({Key? key}) : super(key: key);
@override
_FlowerBudsCountState createState() => _FlowerBudsCountState();
}
class _FlowerBudsCountState extends State<FlowerBudsCount> {
final _scaffoldKey = GlobalKey<ScaffoldState>();
final double topSpace = Utils.displaySize.width * 0.4;
final DatabaseReference _databaseReference = FirebaseDatabase.instance.ref();
List<dynamic> list = [];
DateTime start = DateTime.now();
DateTime end = DateTime.now();
bool useFilters = false;
@override
void initState() {
getData();
super.initState();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
key: _scaffoldKey,
drawer: Drawer(
child: HomeDrawer(
selection: 1,
),
),
backgroundColor: UtilColors.whiteColor,
body: SizedBox(
width: Utils.displaySize.width,
height: Utils.displaySize.height,
child: Column(
children: [
Expanded(
flex: 0,
child: Container(
decoration: BoxDecoration(color: UtilColors.primaryColor),
child: Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0, top: 18.0, bottom: 18.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(
Icons.arrow_left,
color: UtilColors.whiteColor,
),
),
AutoSizeText(
"Flower Buds Count",
style: GoogleFonts.nunitoSans(
fontSize: 18.0, color: UtilColors.whiteColor),
),
GestureDetector(
onTap: () async {
getData();
},
child: Icon(
Icons.refresh,
color: UtilColors.whiteColor,
),
),
],
),
),
)),
const SizedBox(
height: 10.0,
),
Card(
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AutoSizeText(
"Filter",
style: GoogleFonts.nunitoSans(
fontSize: 16.0, color: UtilColors.blackColor),
),
const SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: CustomDateSelectorWithImage(
height: 5,
hint: 'From',
isIconAvailable: false,
icon_img: Icons.calendar_month,
backgroundColor: UtilColors.whiteColor,
type:
CustomDateSelectorWithImage.DATE_TIME_SELECTOR,
onConfirm: (startDateTime) {
start = startDateTime;
}),
),
const SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: CustomDateSelectorWithImage(
height: 5,
hint: 'To',
isIconAvailable: false,
icon_img: Icons.calendar_month,
backgroundColor: UtilColors.whiteColor,
type:
CustomDateSelectorWithImage.DATE_TIME_SELECTOR,
onConfirm: (endDateTime) {
end = endDateTime;
}),
),
const SizedBox(
height: 10.0,
),
SizedBox(
width: double.infinity,
child: TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(
UtilColors.whiteColor),
backgroundColor: MaterialStateProperty.all<Color>(
UtilColors.primaryColor),
),
onPressed: () async {
useFilters = true;
getData();
},
child: Text(
"Filter Records",
style: GoogleFonts.nunitoSans(),
),
))
],
),
),
),
const SizedBox(
height: 10.0,
),
Expanded(
flex: 1,
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: UtilColors.whiteColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0))),
child: Padding(
padding: const EdgeInsets.only(
top: 20.0, bottom: 15.0, left: 15.0, right: 15.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
for (var rec in list)
Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0),
child: Card(
child: ExpansionTile(
expandedAlignment: Alignment.center,
title: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 5.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
flex: 0,
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
Text(
"Buds Count",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
Text(
"Flower Count",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
Text(
"Price",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
],
)),
Expanded(
flex: 1,
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.end,
children: [
Text(
rec['data']
['buds_count']
.toString(),
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
Text(
rec['data'][
'flower_count']
.toString(),
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
Text(
"LKR ${double.parse(rec['data']['price'].toString()).toStringAsFixed(2)}",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
],
))
],
),
const SizedBox(
height: 10.0,
),
Text(
getDateTime(int.parse(
rec['datetime'].toString())),
style: GoogleFonts.nunitoSans(
color:
UtilColors.primaryColor,
fontSize: 12.0),
)
],
),
),
children: <Widget>[
Image.memory(
base64Decode((rec['data']['image']
.toString()
.contains(
'data:image/jpeg;base64,'))
? rec['data']['image']
.toString()
.replaceAll(
'data:image/jpeg;base64,',
'')
: rec['data']['image']),
filterQuality: FilterQuality.low,
),
],
),
),
)
]),
),
),
))
],
)),
));
}
Future<void> getData() async {
_databaseReference
.child(FirebaseStructure.FLOWERBUDSCOUNT)
.once()
.then((DatabaseEvent data) {
list.clear();
for (DataSnapshot element in data.snapshot.children) {
dynamic dataRec = element.value;
if (useFilters == true && start != null && end != null) {
DateTime currentDateTime = DateTime.fromMillisecondsSinceEpoch(
int.parse(dataRec['timestamp'].toString()));
if (currentDateTime.isAfter(start) && currentDateTime.isBefore(end)) {
list.add({'datetime': dataRec['timestamp'], 'data': dataRec});
}
} else {
list.add({'datetime': dataRec['timestamp'], 'data': dataRec});
}
}
setState(() {});
});
}
String getDateTime(int mills) {
return DateFormat('yyyy/MM/dd hh:mm a')
.format(DateTime.fromMillisecondsSinceEpoch(mills));
}
Uint8List getImageString(String value) {
return Uri.parse(value).data!.contentAsBytes();
}
}
import 'dart:convert';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:bloomerang/Models/FirebaseStructure.dart';
import 'package:bloomerang/Views/Home/HomeDrawer.dart';
import 'package:bloomerang/Views/Widgets/custom_date_selector.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:bloomerang/Models/Colors.dart';
import 'package:bloomerang/Models/Utils.dart';
import 'package:intl/intl.dart';
class FlowerDisease extends StatefulWidget {
const FlowerDisease({Key? key}) : super(key: key);
@override
_FlowerDiseaseState createState() => _FlowerDiseaseState();
}
class _FlowerDiseaseState extends State<FlowerDisease> {
final _scaffoldKey = GlobalKey<ScaffoldState>();
final double topSpace = Utils.displaySize.width * 0.4;
final DatabaseReference _databaseReference = FirebaseDatabase.instance.ref();
List<dynamic> list = [];
DateTime start = DateTime.now();
DateTime end = DateTime.now();
bool useFilters = false;
@override
void initState() {
getData();
super.initState();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
key: _scaffoldKey,
drawer: Drawer(
child: HomeDrawer(
selection: 1,
),
),
backgroundColor: UtilColors.whiteColor,
body: SizedBox(
width: Utils.displaySize.width,
height: Utils.displaySize.height,
child: Column(
children: [
Expanded(
flex: 0,
child: Container(
decoration: BoxDecoration(color: UtilColors.primaryColor),
child: Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0, top: 18.0, bottom: 18.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(
Icons.arrow_left,
color: UtilColors.whiteColor,
),
),
AutoSizeText(
"Flower Disease",
style: GoogleFonts.nunitoSans(
fontSize: 18.0, color: UtilColors.whiteColor),
),
GestureDetector(
onTap: () async {
getData();
},
child: Icon(
Icons.refresh,
color: UtilColors.whiteColor,
),
),
],
),
),
)),
const SizedBox(
height: 10.0,
),
Card(
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AutoSizeText(
"Filter",
style: GoogleFonts.nunitoSans(
fontSize: 16.0, color: UtilColors.blackColor),
),
const SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: CustomDateSelectorWithImage(
height: 5,
hint: 'From',
isIconAvailable: false,
icon_img: Icons.calendar_month,
backgroundColor: UtilColors.whiteColor,
type:
CustomDateSelectorWithImage.DATE_TIME_SELECTOR,
onConfirm: (startDateTime) {
start = startDateTime;
}),
),
const SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: CustomDateSelectorWithImage(
height: 5,
hint: 'To',
isIconAvailable: false,
icon_img: Icons.calendar_month,
backgroundColor: UtilColors.whiteColor,
type:
CustomDateSelectorWithImage.DATE_TIME_SELECTOR,
onConfirm: (endDateTime) {
end = endDateTime;
}),
),
const SizedBox(
height: 10.0,
),
SizedBox(
width: double.infinity,
child: TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(
UtilColors.whiteColor),
backgroundColor: MaterialStateProperty.all<Color>(
UtilColors.primaryColor),
),
onPressed: () async {
useFilters = true;
getData();
},
child: Text(
"Filter Records",
style: GoogleFonts.nunitoSans(),
),
))
],
),
),
),
const SizedBox(
height: 10.0,
),
Expanded(
flex: 1,
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: UtilColors.whiteColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0))),
child: Padding(
padding: const EdgeInsets.only(
top: 20.0, bottom: 15.0, left: 15.0, right: 15.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
for (var rec in list)
Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0),
child: Card(
child: ExpansionTile(
expandedAlignment: Alignment.center,
title: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 5.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
flex: 0,
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
Text(
"Disease",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
],
)),
Expanded(
flex: 1,
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.end,
children: [
Text(
rec['data']['disease']
.toString(),
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
)
],
))
],
),
const SizedBox(
height: 10.0,
),
Text(
getDateTime(int.parse(
rec['datetime'].toString())),
style: GoogleFonts.nunitoSans(
color:
UtilColors.primaryColor,
fontSize: 12.0),
)
],
),
),
children: <Widget>[
Image.memory(
base64Decode((rec['data']['image']
.toString()
.contains(
'data:image/jpeg;base64,'))
? rec['data']['image']
.toString()
.replaceAll(
'data:image/jpeg;base64,',
'')
: rec['data']['image']),
filterQuality: FilterQuality.low,
),
FutureBuilder<DatabaseEvent>(
future: _databaseReference
.child(
FirebaseStructure.DISEASES)
.child(rec['data']['disease']
.toString()
.toLowerCase()
.replaceAll(' ', ''))
.once(),
builder: (context,
AsyncSnapshot<DatabaseEvent>
snapshot) {
if (snapshot.connectionState ==
ConnectionState.done) {
if (snapshot.hasData) {
dynamic map = snapshot
.data!.snapshot.value;
return Padding(
padding:
const EdgeInsets.all(
10.0),
child: Wrap(
children: [
Padding(
padding:
const EdgeInsets
.symmetric(
vertical:
5.0),
child: Text(
"Description",
style: TextStyle(
color: UtilColors
.blackColor,
fontSize:
16.0)),
),
Padding(
padding:
const EdgeInsets
.symmetric(
vertical:
10.0),
child: Text(
map['description'],
style: TextStyle(
color: UtilColors
.greyColorDark,
fontSize:
14.0)),
),
Padding(
padding:
const EdgeInsets
.only(top: 20.0) ,
child: Text(
"Solution",
style: TextStyle(
color: UtilColors
.primaryColor,
fontSize:
16.0)),
),
Padding(
padding:
const EdgeInsets
.symmetric(
vertical:
10.0),
child: Text(
map['solution'],
style: TextStyle(
color: UtilColors
.primaryColor,
fontSize:
14.0)),
),
],
),
);
}
return const SizedBox.shrink();
}
return const Padding(
padding: EdgeInsets.symmetric(
vertical: 20.0),
child:
CircularProgressIndicator(),
);
})
],
),
),
)
]),
),
),
))
],
)),
));
}
Future<void> getData() async {
_databaseReference
.child(FirebaseStructure.FLOWERDISEASE)
.once()
.then((DatabaseEvent data) {
list.clear();
for (DataSnapshot element in data.snapshot.children) {
dynamic dataRec = element.value;
if (useFilters == true && start != null && end != null) {
DateTime currentDateTime = DateTime.fromMillisecondsSinceEpoch(
int.parse(dataRec['timestamp'].toString()));
if (currentDateTime.isAfter(start) && currentDateTime.isBefore(end)) {
list.add({'datetime': dataRec['timestamp'], 'data': dataRec});
}
} else {
list.add({'datetime': dataRec['timestamp'], 'data': dataRec});
}
}
setState(() {});
});
}
String getDateTime(int mills) {
return DateFormat('yyyy/MM/dd hh:mm a')
.format(DateTime.fromMillisecondsSinceEpoch(mills));
}
Uint8List getImageString(String value) {
return Uri.parse(value).data!.contentAsBytes();
}
}
import 'dart:convert';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:bloomerang/Models/FirebaseStructure.dart';
import 'package:bloomerang/Views/Home/HomeDrawer.dart';
import 'package:bloomerang/Views/Widgets/GraphView.dart';
import 'package:bloomerang/Views/Widgets/custom_date_selector.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:bloomerang/Models/Colors.dart';
import 'package:bloomerang/Models/Utils.dart';
import 'package:intl/intl.dart';
class FlowerFreshness extends StatefulWidget {
const FlowerFreshness({Key? key}) : super(key: key);
@override
_FlowerFreshnessState createState() => _FlowerFreshnessState();
}
class _FlowerFreshnessState extends State<FlowerFreshness> {
final _scaffoldKey = GlobalKey<ScaffoldState>();
final double topSpace = Utils.displaySize.width * 0.4;
final DatabaseReference _databaseReference = FirebaseDatabase.instance.ref();
List<dynamic> list = [];
DateTime start = DateTime.now();
DateTime end = DateTime.now();
bool useFilters = false;
@override
void initState() {
getData();
super.initState();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
key: _scaffoldKey,
drawer: Drawer(
child: HomeDrawer(
selection: 1,
),
),
backgroundColor: UtilColors.whiteColor,
body: SizedBox(
width: Utils.displaySize.width,
height: Utils.displaySize.height,
child: Column(
children: [
Expanded(
flex: 0,
child: Container(
decoration: BoxDecoration(color: UtilColors.primaryColor),
child: Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0, top: 18.0, bottom: 18.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(
Icons.arrow_left,
color: UtilColors.whiteColor,
),
),
AutoSizeText(
"Flower Freshness",
style: GoogleFonts.nunitoSans(
fontSize: 18.0, color: UtilColors.whiteColor),
),
GestureDetector(
onTap: () async {
getData();
},
child: Icon(
Icons.refresh,
color: UtilColors.whiteColor,
),
),
],
),
),
)),
const SizedBox(
height: 10.0,
),
Card(
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AutoSizeText(
"Filter",
style: GoogleFonts.nunitoSans(
fontSize: 16.0, color: UtilColors.blackColor),
),
const SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: CustomDateSelectorWithImage(
height: 5,
hint: 'From',
isIconAvailable: false,
icon_img: Icons.calendar_month,
backgroundColor: UtilColors.whiteColor,
type:
CustomDateSelectorWithImage.DATE_TIME_SELECTOR,
onConfirm: (startDateTime) {
start = startDateTime;
}),
),
const SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: CustomDateSelectorWithImage(
height: 5,
hint: 'To',
isIconAvailable: false,
icon_img: Icons.calendar_month,
backgroundColor: UtilColors.whiteColor,
type:
CustomDateSelectorWithImage.DATE_TIME_SELECTOR,
onConfirm: (endDateTime) {
end = endDateTime;
}),
),
const SizedBox(
height: 10.0,
),
SizedBox(
width: double.infinity,
child: TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(
UtilColors.whiteColor),
backgroundColor: MaterialStateProperty.all<Color>(
UtilColors.primaryColor),
),
onPressed: () async {
useFilters = true;
getData();
},
child: Text(
"Filter Records",
style: GoogleFonts.nunitoSans(),
),
))
],
),
),
),
const SizedBox(
height: 10.0,
),
Expanded(
flex: 1,
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: UtilColors.whiteColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0))),
child: Padding(
padding: const EdgeInsets.only(
top: 20.0, bottom: 15.0, left: 15.0, right: 15.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
for (var rec in list)
Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0),
child: Card(
child: ExpansionTile(
expandedAlignment: Alignment.center,
title: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 5.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
flex: 0,
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
Text(
"Freshness",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
],
)),
Expanded(
flex: 1,
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.end,
children: [
Text(
rec['data']
['freshness']
.toString(),
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
)
],
))
],
),
const SizedBox(
height: 10.0,
),
Text(
getDateTime(int.parse(
rec['datetime'].toString())),
style: GoogleFonts.nunitoSans(
color:
UtilColors.primaryColor,
fontSize: 12.0),
)
],
),
),
children: <Widget>[
Image.memory(
base64Decode((rec['data']['image']
.toString()
.contains(
'data:image/jpeg;base64,'))
? rec['data']['image']
.toString()
.replaceAll(
'data:image/jpeg;base64,',
'')
: rec['data']['image']),
filterQuality: FilterQuality.low,
),
],
),
),
)
]),
),
),
))
],
)),
));
}
Future<void> getData() async {
_databaseReference
.child(FirebaseStructure.FlowerFreshness)
.once()
.then((DatabaseEvent data) {
list.clear();
for (DataSnapshot element in data.snapshot.children) {
dynamic dataRec = element.value;
if (useFilters == true && start != null && end != null) {
DateTime currentDateTime = DateTime.fromMillisecondsSinceEpoch(
int.parse(dataRec['timestamp'].toString()));
if (currentDateTime.isAfter(start) && currentDateTime.isBefore(end)) {
list.add({'datetime': dataRec['timestamp'], 'data': dataRec});
}
} else {
list.add({'datetime': dataRec['timestamp'], 'data': dataRec});
}
}
setState(() {});
});
}
String getDateTime(int mills) {
return DateFormat('yyyy/MM/dd hh:mm a')
.format(DateTime.fromMillisecondsSinceEpoch(mills));
}
Uint8List getImageString(String value) {
return Uri.parse(value).data!.contentAsBytes();
}
}
import 'dart:convert';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:bloomerang/Views/Widgets/GraphView.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:bloomerang/Models/FirebaseStructure.dart';
import 'package:bloomerang/Views/Home/HomeDrawer.dart';
import 'package:bloomerang/Views/Widgets/custom_date_selector.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:bloomerang/Models/Colors.dart';
import 'package:bloomerang/Models/Utils.dart';
import 'package:intl/intl.dart';
class History extends StatefulWidget {
const History({Key? key}) : super(key: key);
@override
_HistoryState createState() => _HistoryState();
}
class _HistoryState extends State<History> {
final _scaffoldKey = GlobalKey<ScaffoldState>();
final double topSpace = Utils.displaySize.width * 0.4;
final DatabaseReference _databaseReference = FirebaseDatabase.instance.ref();
List<dynamic> list = [];
DateTime start = DateTime.now();
DateTime end = DateTime.now();
bool useFilters = false;
@override
void initState() {
getData();
super.initState();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
key: _scaffoldKey,
drawer: Drawer(
child: HomeDrawer(
selection: 1,
),
),
backgroundColor: UtilColors.whiteColor,
body: SizedBox(
width: Utils.displaySize.width,
height: Utils.displaySize.height,
child: Column(
children: [
Expanded(
flex: 0,
child: Container(
decoration: BoxDecoration(color: UtilColors.primaryColor),
child: Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0, top: 18.0, bottom: 18.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(
Icons.arrow_left,
color: UtilColors.whiteColor,
),
),
AutoSizeText(
"History",
style: GoogleFonts.nunitoSans(
fontSize: 18.0, color: UtilColors.whiteColor),
),
GestureDetector(
onTap: () async {
viewGraph();
},
child: Icon(
Icons.graphic_eq,
color: UtilColors.whiteColor,
),
),
],
),
),
)),
const SizedBox(
height: 10.0,
),
Card(
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AutoSizeText(
"Filter",
style: GoogleFonts.nunitoSans(
fontSize: 16.0, color: UtilColors.blackColor),
),
const SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: CustomDateSelectorWithImage(
height: 5,
hint: 'From',
isIconAvailable: false,
icon_img: Icons.calendar_month,
backgroundColor: UtilColors.whiteColor,
type:
CustomDateSelectorWithImage.DATE_TIME_SELECTOR,
onConfirm: (startDateTime) {
start = startDateTime;
}),
),
const SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: CustomDateSelectorWithImage(
height: 5,
hint: 'To',
isIconAvailable: false,
icon_img: Icons.calendar_month,
backgroundColor: UtilColors.whiteColor,
type:
CustomDateSelectorWithImage.DATE_TIME_SELECTOR,
onConfirm: (endDateTime) {
end = endDateTime;
}),
),
const SizedBox(
height: 10.0,
),
SizedBox(
width: double.infinity,
child: TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(
UtilColors.whiteColor),
backgroundColor: MaterialStateProperty.all<Color>(
UtilColors.primaryColor),
),
onPressed: () async {
useFilters = true;
getData();
},
child: Text(
"Filter Records",
style: GoogleFonts.nunitoSans(),
),
))
],
),
),
),
const SizedBox(
height: 10.0,
),
Expanded(
flex: 1,
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: UtilColors.whiteColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0))),
child: Padding(
padding: const EdgeInsets.only(
top: 20.0, bottom: 15.0, left: 15.0, right: 15.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
for (var rec in list)
Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0),
child: Card(
child: ListTile(
title: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 5.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
flex: 0,
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
Text(
"Fan",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
Text(
"Humidity Fire",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
Text(
"Pump",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
Text(
"Soil",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
Text(
"LDR Status",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
Text(
"Humidity",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
Text(
"LUX",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
Text(
"PH",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
Text(
"Temprature",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
Text(
"Turbidity",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
Text(
"Water Level",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
Text(
"Water Temprature",
style: GoogleFonts
.nunitoSans(
color: UtilColors
.blackColor),
),
],
)),
Expanded(
flex: 1,
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.end,
children: [
getTextBool(rec['data']
['fan']
.toString()),
getTextBool(rec['data'][
'humidity_fire']
.toString()),
getTextBool(rec['data']
['pump']
.toString()),
getTextBool(rec['data']
['soil']
.toString()),
getLDRBool(rec['data']
['ldr_status']
.toString()),
getText(
double.parse(rec[
'data']
['humidity']
.toString()),
"%"),
getText(
double.parse(rec[
'data']
['lux']
.toString()),
"lx"),
getText(
double.parse(rec[
'data']
['ph']
.toString()),
"ph"),
getText(
double.parse(rec[
'data'][
'temperature']
.toString()),
"°C"),
getText(
double.parse(rec[
'data'][
'turbidity']
.toString()),
"%"),
getText(
double.parse(rec[
'data'][
'water_level']
.toString()),
"%"),
getText(
double.parse(rec[
'data'][
'water_temperature']
.toString()),
"°C"),
],
))
],
),
const SizedBox(
height: 10.0,
),
Text(
getDateTime(int.parse(
rec['datetime'].toString())),
style: GoogleFonts.nunitoSans(
color:
UtilColors.primaryColor,
fontSize: 12.0),
)
],
),
),
),
),
)
]),
),
),
))
],
)),
));
}
Future<void> viewGraph() async {
if (list.isNotEmpty) {
final List<ChartData> chartData1 = [];
final List<ChartData> chartData2 = [];
final List<ChartData> chartData3 = [];
for (var element in list) {
chartData1.add(ChartData(getDateTime(int.parse(element['datetime'])),
double.parse(element['data']['humidity'].toString())));
chartData2.add(ChartData(getDateTime(int.parse(element['datetime'])),
double.parse(element['data']['temperature'].toString())));
chartData3.add(ChartData(getDateTime(int.parse(element['datetime'])),
double.parse(element['data']['turbidity'].toString())));
}
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return GraphView(
chartData1: chartData1,
chartData2: chartData2,
chartData3: chartData3,
label1: "Humidity",
label2: "Temperature",
label3: "Turbidity");
});
} else {
Utils.showToast("No data found to create graph");
}
}
Future<void> getData() async {
_databaseReference
.child(FirebaseStructure.HISTORY)
.once()
.then((DatabaseEvent data) {
list.clear();
for (DataSnapshot element in data.snapshot.children) {
if (useFilters == true && start != null && end != null) {
DateTime currentDateTime = DateTime.fromMillisecondsSinceEpoch(
int.parse(element.key.toString()));
if (currentDateTime.isAfter(start) && currentDateTime.isBefore(end)) {
list.add(
{'datetime': element.key.toString(), 'data': element.value});
}
} else {
list.add({'datetime': element.key.toString(), 'data': element.value});
}
}
setState(() {});
});
}
String getDateTime(int mills) {
return DateFormat('yyyy/MM/dd hh:mm a')
.format(DateTime.fromMillisecondsSinceEpoch(mills));
}
Uint8List getImageString(String value) {
return Uri.parse(value).data!.contentAsBytes();
}
Widget getTextBool(String value) {
return Text(
value == 'true' ? 'ON' : 'OFF',
style: GoogleFonts.nunitoSans(
color: (value == 'true')
? UtilColors.primaryColor
: UtilColors.redColor),
);
}
Widget getLDRBool(String value) {
return Text(
value,
style: GoogleFonts.nunitoSans(
color: (value == 'Day')
? UtilColors.yellowColor
: UtilColors.blackColor),
);
}
Widget getText(double value, String prefix) {
return Text(
value.toString() + prefix,
style: GoogleFonts.nunitoSans(
color: (value > 50) ? UtilColors.primaryColor : UtilColors.redColor),
);
}
}
import 'dart:async';
import 'package:animate_do/animate_do.dart';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:bloomerang/Models/Images.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:bloomerang/Models/FirebaseStructure.dart';
import 'package:bloomerang/Models/Strings.dart';
import 'package:bloomerang/Views/Home/HomeDrawer.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:bloomerang/Models/Colors.dart';
import 'package:bloomerang/Models/Utils.dart';
import 'package:syncfusion_flutter_gauges/gauges.dart';
import 'package:toggle_switch/toggle_switch.dart';
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
final _scaffoldKey = GlobalKey<ScaffoldState>();
final double topSpace = Utils.displaySize.width * 0.4;
bool processChecking = true;
final DatabaseReference _databaseReference = FirebaseDatabase.instance.ref();
List<dynamic> fishList = [];
bool _visible = true;
late Timer _timer;
late StreamSubscription<DatabaseEvent> _streamSubscription;
double fan = 0;
double humidity = 0;
double humidity_fire = 0;
double ldr_status = 0;
double lux = 0;
double mode = 0;
double ph = 0;
double pump = 0;
double soil = 0;
double temperature = 0;
double turbidity = 0;
double water_level = 0;
double water_temperature = 0;
@override
void initState() {
super.initState();
liveUpdate();
initNotifications();
initLiveAnimation();
}
@override
void dispose() {
_streamSubscription.cancel();
_timer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
key: _scaffoldKey,
drawer: Drawer(
child: HomeDrawer(
selection: 1,
),
),
body: SizedBox(
width: Utils.displaySize.width,
height: Utils.displaySize.height,
child: Column(
children: [
Expanded(
flex: 0,
child: Container(
decoration: BoxDecoration(
color: UtilColors.primaryColor.withOpacity(0.3),
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(20.0),
bottomRight: Radius.circular(20.0)),
),
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
if (_scaffoldKey.currentState!.hasDrawer &&
_scaffoldKey.currentState!.isEndDrawerOpen) {
_scaffoldKey.currentState!.openEndDrawer();
} else {
_scaffoldKey.currentState!.openDrawer();
}
},
child: Icon(
Icons.menu,
color: UtilColors.blackColor,
),
),
SizedBox(
width: 40.0,
child: Image.asset(UtilImages.logoPNG),
),
AnimatedOpacity(
opacity: _visible ? 1.0 : 0.0,
duration: const Duration(milliseconds: 2000),
child: Icon(
Icons.adjust,
color: UtilColors.redColor,
),
),
],
),
),
)),
Expanded(
flex: 1,
child: SingleChildScrollView(
child: Column(
children: [
getLiveDataCard(
Icons.switch_left,
"Mode",
"Enable the switches",
0,
1,
mode,
"",
true,
false,
'mode', []),
getLiveDataCard(
Icons.wind_power_outlined,
"Fan",
"Fan status",
0,
1,
fan,
"",
(mode == 1.0),
mode == 0.0,
'fan', []),
getLiveDataCard(
Icons.water_drop,
"Humidity",
"Humidity status",
0,
1,
humidity_fire,
"",
(mode == 1.0),
mode == 0.0,
'humidity_fire', []),
getLiveDataCard(
Icons.heat_pump,
"Pump",
"Pump status",
0,
1,
pump,
"",
(mode == 1.0),
mode == 0.0,
'pump', []),
getLiveDataCard(Icons.science, "Soil", "Soil status", 0,
1, soil, "", false, mode == 0.0, 'soil', []),
getLiveDataCard(
Icons.lightbulb,
"LDR",
"LDR status",
0,
1,
ldr_status,
ldr_status == 0 ? "Night" : "Day",
false,
false,
null,
[Icons.dark_mode, Icons.sunny]),
getLiveDataCard(
Icons.water_damage_rounded,
"Humidity",
"graph view of humidity",
0,
100,
humidity.toInt(),
"%",
false,
false,
null, []),
getLiveDataCard(Icons.light, "Lux", "graph view of lux",
0, 5000, lux.toInt(), "lx", false, false, null, []),
getLiveDataCard(
Icons.blur_on,
"PH Value",
"graph view of ph value",
0,
14,
ph,
"ph",
false,
false,
null, []),
getLiveDataCard(
Icons.thermostat,
"Temperature",
"graph view of temperature",
0,
100,
temperature.toInt(),
"°C",
false,
false,
null, []),
getLiveDataCard(
Icons.cloud,
"Turbidity",
"graph view of turbidity",
0,
100,
turbidity.toInt(),
"%",
false,
false,
null, []),
getLiveDataCard(
Icons.waterfall_chart,
"Water Level",
"graph view of water level",
0,
100,
water_level.toInt(),
"%",
false,
false,
null, []),
getLiveDataCard(
Icons.thermostat_auto,
"Water Temperature",
"graph view of water temperature",
0,
100,
water_temperature.toInt(),
"°C",
false,
false,
null, []),
],
),
))
],
)),
));
}
Widget getLiveDataCard(
IconData icon,
String title,
String subTitle,
double minValue,
double maxValue,
dynamic value,
String valueText,
bool changable,
bool showAsDisable,
String? onChangeVal,
List<IconData> icons) {
Color valueColor = UtilColors.greyColor;
subTitle = subTitle.toUpperCase();
if (maxValue > 1) {
List<GaugeRange> colors = [
GaugeRange(
startValue: minValue,
endValue: (maxValue / 2),
color: UtilColors.redColor),
GaugeRange(
startValue: (maxValue / 2),
endValue: maxValue,
color: UtilColors.primaryColor)
];
return Expanded(
flex: 0,
child: Padding(
padding: const EdgeInsets.only(top: 10.0, right: 10.0, left: 10.0),
child: SizedBox(
width: double.infinity,
child: Card(
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 20.0, horizontal: 15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: Icon(
icon,
size: 35.0,
color: (value > (maxValue / 2))
? UtilColors.primaryColor
: UtilColors.redColor,
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: GoogleFonts.nunitoSans(
fontSize: 18.0,
color: UtilColors.blackColor,
fontWeight: FontWeight.w400,
),
),
Text(
subTitle,
style: GoogleFonts.nunitoSans(
fontSize: 10.0,
color: UtilColors.greyColorDark,
fontWeight: FontWeight.w400,
),
),
],
)
],
),
Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Divider(
color: UtilColors.greyColorDark,
height: 5.0,
),
),
Align(
alignment: Alignment.center,
child: Padding(
padding: const EdgeInsets.only(top: 20.0),
child: SizedBox(
width: Utils.displaySize.width * 0.6,
height: Utils.displaySize.width * 0.6,
child: SfRadialGauge(
animationDuration: 2000,
enableLoadingAnimation: true,
axes: <RadialAxis>[
RadialAxis(
minimum: minValue,
maximum: maxValue,
ranges: colors,
pointers: <GaugePointer>[
NeedlePointer(value: value.toDouble())
],
annotations: <GaugeAnnotation>[
GaugeAnnotation(
widget: Text(
value.toString() + valueText,
style: GoogleFonts.nunitoSans(
color: valueColor,
fontSize: 20,
fontWeight:
FontWeight.bold)),
angle: 90,
positionFactor: 0.5)
])
]),
),
),
)
],
),
),
),
),
));
}
dynamic onChange = (onChangeVal != null && changable)
? (index) {
changeStatus(onChangeVal, (value == 0.0) ? 'true' : 'false');
}
: (index) {};
return Expanded(
flex: 0,
child: Padding(
padding: const EdgeInsets.only(top: 10.0, right: 10.0, left: 10.0),
child: SizedBox(
width: double.infinity,
child: Card(
color: ((icons.isEmpty)
? onChangeVal != null && changable
? UtilColors.whiteColor
: UtilColors.greyColorLight
: UtilColors.whiteColor),
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 20.0, horizontal: 15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: Icon(
icon,
size: 35.0,
color: value == 1
? UtilColors.primaryColor
.withOpacity(((icons.isEmpty)
? (onChangeVal != null && changable)
? 1.0
: 0.5
: 1.0))
: UtilColors.redColor
.withOpacity(((icons.isEmpty)
? (onChangeVal != null && changable)
? 1.0
: 0.5
: 1.0)),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: GoogleFonts.nunitoSans(
fontSize: 18.0,
color: UtilColors.blackColor,
fontWeight: FontWeight.w400,
),
),
Text(
subTitle,
style: GoogleFonts.nunitoSans(
fontSize: 10.0,
color: UtilColors.greyColorDark,
fontWeight: FontWeight.w400,
),
),
],
),
],
),
Column(
children: [
(icons.isNotEmpty)
? Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
valueText,
style: GoogleFonts.nunitoSans(
fontSize: 15.0,
color: (value == 1)
? UtilColors.yellowColor
: UtilColors.blackColor,
fontWeight: FontWeight.w400,
),
),
Icon(
icons[value.toInt()],
size: 20.0,
color: (value == 1)
? UtilColors.yellowColor
: UtilColors.blackColor,
)
],
)
: ToggleSwitch(
changeOnTap: changable,
activeBgColor: (value == 1)
? [
(onChangeVal != null && changable)
? UtilColors.primaryColor
: UtilColors.primaryColor
.withOpacity(0.4),
]
: [
(onChangeVal != null && changable)
? UtilColors.redColor
: UtilColors.redColor
.withOpacity(0.4),
],
inactiveBgColor: (onChangeVal != null &&
changable)
? UtilColors.greyColor
: UtilColors.greyColor.withOpacity(0.5),
inactiveFgColor: UtilColors.whiteColor,
initialLabelIndex: (value == 1) ? 0 : 1,
totalSwitches: 2,
labels: const ['ON', 'OFF'],
onToggle: onChange,
)
],
)
],
)
],
),
),
),
),
));
}
Future<void> liveUpdate() async {
_streamSubscription = _databaseReference
.child(FirebaseStructure.LIVEDATA)
.onValue
.listen((DatabaseEvent data) {
dynamic resp = data.snapshot.value;
setState(() {
fan = (resp['fan'] != null && resp['fan'] == 'true') ? 1 : 0;
humidity_fire =
(resp['humidity_fire'] != null && resp['humidity_fire'] == 'true')
? 1
: 0;
mode = (resp['mode'] != null && resp['mode'] == 'true') ? 1 : 0;
pump = (resp['pump'] != null && resp['pump'] == 'true') ? 1 : 0;
soil = (resp['soil'] != null && resp['soil'] == 'true') ? 1 : 0;
ldr_status =
(resp['ldr_status'] != null && resp['ldr_status'] == 'Day') ? 1 : 0;
humidity =
(resp['humidity'] != null) ? double.parse(resp['humidity']) : 0;
lux = (resp['lux'] != null) ? double.parse(resp['lux']) : 0;
ph = (resp['ph'] != null) ? double.parse(resp['ph']) : 0;
temperature = (resp['temperature'] != null)
? double.parse(resp['temperature'])
: 0;
turbidity =
(resp['turbidity'] != null) ? double.parse(resp['turbidity']) : 0;
water_level = (resp['water_level'] != null)
? double.parse(resp['water_level'])
: 0;
water_temperature = (resp['water_temperature'] != null)
? double.parse(resp['water_temperature'])
: 0;
});
});
}
void initNotifications() {
AwesomeNotifications().isNotificationAllowed().then((isAllowed) {
if (!isAllowed) {
AwesomeNotifications().requestPermissionToSendNotifications();
} else {
_databaseReference
.child(FirebaseStructure.NOTIFICATION)
.onValue
.listen((DatabaseEvent data) async {
dynamic noti = data.snapshot.value;
if (noti['status'] == "1" || noti['status'] == 1) {
AwesomeNotifications().createNotification(
content: NotificationContent(
id: -1,
channelKey: 'emergency_bloomerang',
title: 'Notification',
body: noti['description'].toString()));
await _databaseReference
.child(FirebaseStructure.NOTIFICATION)
.child('status')
.set(0);
}
});
}
});
}
void initLiveAnimation() {
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
setState(() {
_visible = !_visible;
});
});
}
void changeStatus(String factor, String bool) {
_databaseReference
.child(FirebaseStructure.LIVEDATA)
.child(factor)
.set(bool);
}
}
import 'package:bloomerang/Controllers/AuthController.dart';
import 'package:bloomerang/Models/Colors.dart';
import 'package:bloomerang/Models/Images.dart';
import 'package:bloomerang/Models/Utils.dart';
import 'package:bloomerang/Views/Diseases/Diseases.dart';
import 'package:bloomerang/Views/FlowerBudsCount/FlowerBudsCount.dart';
import 'package:bloomerang/Views/FlowerDisease/FlowerDisease.dart';
import 'package:bloomerang/Views/FlowerFreshness/FlowerFreshness.dart';
import 'package:bloomerang/Views/History/History.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class HomeDrawer extends StatefulWidget {
int selection = 1;
HomeDrawer({Key? key, required selection}) : super(key: key);
@override
_HomeDrawerState createState() => _HomeDrawerState(selection: selection);
}
class _HomeDrawerState extends State<HomeDrawer> {
int selection;
_HomeDrawerState({required this.selection});
final AuthController _authController = AuthController();
@override
Widget build(BuildContext context) {
return ListView(
children: [
Container(
width: double.infinity,
height: Utils.displaySize.height * 0.15,
decoration: Utils.getGradientBackground(),
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
height: 60.0,
width: 60.0,
child: ClipOval(
child: Image.asset(
UtilImages.userPNG,
fit: BoxFit.cover,
),
),
),
Padding(
padding: const EdgeInsets.only(left: 20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
Utils.profileUser.name.toString().toUpperCase(),
style: GoogleFonts.nunitoSans(
color: UtilColors.whiteColor,
fontWeight: FontWeight.w600),
),
const SizedBox(
height: 5.0,
),
Text(
Utils.profileUser.email.toString(),
style: GoogleFonts.nunitoSans(
color: UtilColors.whiteColor,
fontSize: 10.0,
fontWeight: FontWeight.w600),
),
const SizedBox(
height: 5.0,
),
Text(
Utils.profileUser.mobile.toString(),
style: GoogleFonts.nunitoSans(
color: UtilColors.whiteColor,
fontSize: 10.0,
fontWeight: FontWeight.w600),
)
],
))
],
),
),
),
ListTile(
tileColor: (selection == 1)
? UtilColors.primaryColor.withOpacity(0.3)
: UtilColors.whiteColor,
leading: Icon(
Icons.home,
color: UtilColors.blackColor.withOpacity(0.8),
),
title: Text(
'Home',
style: GoogleFonts.nunitoSans(
color: UtilColors.blackColor, fontWeight: FontWeight.w400),
),
trailing: Icon(
Icons.arrow_forward_ios,
color: UtilColors.primaryColor,
size: 15.0,
),
),
ListTile(
leading: Icon(
Icons.spa,
color: UtilColors.blackColor.withOpacity(0.8),
),
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (_) => const FlowerBudsCount()));
},
title: Text(
'Flower Buds Count',
style: GoogleFonts.nunitoSans(
color: UtilColors.blackColor, fontWeight: FontWeight.w400),
),
trailing: Icon(
Icons.arrow_forward_ios,
color: UtilColors.primaryColor,
size: 15.0,
),
),
ListTile(
leading: Icon(
Icons.cloud_sync,
color: UtilColors.blackColor.withOpacity(0.8),
),
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (_) => const FlowerFreshness()));
},
title: Text(
'Flower Freshness',
style: GoogleFonts.nunitoSans(
color: UtilColors.blackColor, fontWeight: FontWeight.w400),
),
trailing: Icon(
Icons.arrow_forward_ios,
color: UtilColors.primaryColor,
size: 15.0,
),
),
ListTile(
leading: Icon(
Icons.coronavirus,
color: UtilColors.blackColor.withOpacity(0.8),
),
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (_) => const FlowerDisease()));
},
title: Text(
'Flower Disease',
style: GoogleFonts.nunitoSans(
color: UtilColors.blackColor, fontWeight: FontWeight.w400),
),
trailing: Icon(
Icons.arrow_forward_ios,
color: UtilColors.primaryColor,
size: 15.0,
),
),
ListTile(
leading: Icon(
Icons.coronavirus_sharp,
color: UtilColors.blackColor.withOpacity(0.8),
),
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (_) => const Diseases()));
},
title: Text(
'Diseases',
style: GoogleFonts.nunitoSans(
color: UtilColors.blackColor, fontWeight: FontWeight.w400),
),
trailing: Icon(
Icons.arrow_forward_ios,
color: UtilColors.primaryColor,
size: 15.0,
),
),
ListTile(
leading: Icon(
Icons.history,
color: UtilColors.blackColor.withOpacity(0.8),
),
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (_) => const History()));
},
title: Text(
'History',
style: GoogleFonts.nunitoSans(
color: UtilColors.blackColor, fontWeight: FontWeight.w400),
),
trailing: Icon(
Icons.arrow_forward_ios,
color: UtilColors.primaryColor,
size: 15.0,
),
),
ListTile(
leading: Icon(
Icons.logout,
color: UtilColors.blackColor.withOpacity(0.8),
),
onTap: () {
AuthController().logout(context);
},
title: Text(
'Logout',
style: GoogleFonts.nunitoSans(
color: UtilColors.blackColor, fontWeight: FontWeight.w400),
),
trailing: Icon(
Icons.arrow_forward_ios,
color: UtilColors.primaryColor,
size: 15.0,
)),
],
);
}
}
import 'package:auto_size_text/auto_size_text.dart';
import 'package:bloomerang/Views/Home/HomeDrawer.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:bloomerang/Models/Colors.dart';
import 'package:bloomerang/Models/Utils.dart';
import 'package:intl/intl.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class GraphView extends StatefulWidget {
dynamic chartData1 = [];
dynamic chartData2 = [];
dynamic chartData3 = [];
dynamic label1, label2, label3;
GraphView(
{Key? key,
required this.chartData1,
this.chartData2,
this.chartData3,
this.label1,
this.label3,
this.label2})
: super(key: key);
@override
_GraphViewState createState() => _GraphViewState(
chartData1: this.chartData1,
chartData2: (this.chartData2 != null) ? this.chartData2 : [],
chartData3: (this.chartData3 != null) ? this.chartData3 : [],
label1: this.label1,
label3: this.label3,
label2: this.label2);
}
class _GraphViewState extends State<GraphView> {
List<ChartData> chartData1 = [];
List<ChartData> chartData2 = [];
List<ChartData> chartData3 = [];
dynamic label1, label2, label3;
final List<ChartSeries> chartSeries = [];
_GraphViewState(
{required this.chartData1,
required this.chartData2,
required this.chartData3,
required this.label1,
required this.label2,
required this.label3});
final _scaffoldKey = GlobalKey<ScaffoldState>();
final double topSpace = Utils.displaySize.width * 0.4;
@override
void initState() {
finializeData();
super.initState();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
key: _scaffoldKey,
backgroundColor: UtilColors.whiteColor,
body: SizedBox(
width: Utils.displaySize.width,
height: Utils.displaySize.height,
child: Column(
children: [
Expanded(
flex: 0,
child: Container(
decoration: BoxDecoration(color: UtilColors.primaryColor),
child: Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0, top: 18.0, bottom: 18.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
Icons.refresh,
color: UtilColors.primaryColor,
),
AutoSizeText(
"Graph View",
style: GoogleFonts.nunitoSans(
fontSize: 18.0, color: UtilColors.whiteColor),
),
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(
Icons.close,
color: UtilColors.whiteColor,
),
),
],
),
),
)),
Expanded(
child: (chartSeries.isNotEmpty)
? Align(
alignment: Alignment.bottomCenter,
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
series: chartSeries),
)
: const SizedBox.shrink()),
(label1 != null)
? Expanded(
flex: 0,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20.0, vertical: 5.0),
child: Column(
children: [
Row(
children: [
Container(
color: UtilColors.blueColor,
height: 10.0,
width: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 10.0),
child: Text(
label1,
style: GoogleFonts.nunitoSans(
color: UtilColors.blackColor,
fontWeight: FontWeight.w500,
fontSize: 15.0),
),
)
],
),
],
),
),
)
: const SizedBox.shrink(),
(label2 != null)
? Expanded(
flex: 0,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20.0, vertical: 5.0),
child: Column(
children: [
Row(
children: [
Container(
color: UtilColors.redColor,
height: 10.0,
width: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 10.0),
child: Text(
label2,
style: GoogleFonts.nunitoSans(
color: UtilColors.blackColor,
fontWeight: FontWeight.w500,
fontSize: 15.0),
),
)
],
),
],
),
),
)
: const SizedBox.shrink(),
(label3 != null)
? Expanded(
flex: 0,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20.0, vertical: 5.0),
child: Column(
children: [
Row(
children: [
Container(
color: UtilColors.purpleColor,
height: 10.0,
width: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 10.0),
child: Text(
label3,
style: GoogleFonts.nunitoSans(
color: UtilColors.blackColor,
fontWeight: FontWeight.w500,
fontSize: 15.0),
),
)
],
),
],
),
),
)
: const SizedBox.shrink()
],
)),
));
}
void finializeData() {
setState(() {
if (chartData1.isNotEmpty) {
chartSeries.add(SplineSeries<ChartData, String>(
dataSource: chartData1,
// splineType: SplineType.cardinal,
// cardinalSplineTension: 0.9,
markerSettings: const MarkerSettings(isVisible: true),
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y));
}
if (chartData2.isNotEmpty) {
chartSeries.add(SplineSeries<ChartData, String>(
dataSource: chartData2,
// splineType: SplineType.cardinal,
// cardinalSplineTension: 0.9,
markerSettings: const MarkerSettings(isVisible: true),
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y));
}
if (chartData3.isNotEmpty) {
chartSeries.add(SplineSeries<ChartData, String>(
dataSource: chartData3,
color: UtilColors.purpleColor,
// splineType: SplineType.cardinal,
// cardinalSplineTension: 0.9,
markerSettings: const MarkerSettings(isVisible: true),
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y));
}
});
}
}
class ChartData {
ChartData(this.x, this.y);
final String x;
final double? y;
}
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:bloomerang/Models/Colors.dart';
import 'package:bloomerang/Models/Utils.dart';
class Confirmation extends StatefulWidget {
@override
State<StatefulWidget> createState() => ConfirmationState();
}
class ConfirmationState extends State<Confirmation>
with SingleTickerProviderStateMixin {
@override
Widget build(BuildContext context) {
return Center(
child: Material(
color: Colors.transparent,
child: SizedBox(
child: Card(
child: Column(
children: [Text('Confirmation')],
),
),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:bloomerang/Models/Colors.dart';
import 'package:bloomerang/Models/Utils.dart';
class PopUpLoading extends StatefulWidget {
@override
State<StatefulWidget> createState() => PopUpLoadingState();
}
class PopUpLoadingState extends State<PopUpLoading>
with SingleTickerProviderStateMixin {
late AnimationController controller;
late Animation<double> scaleAnimation;
@override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: Duration(milliseconds: 450));
scaleAnimation =
CurvedAnimation(parent: controller, curve: Curves.elasticInOut);
controller.addListener(() {
setState(() {});
});
controller.forward();
}
@override
dispose() {
controller.dispose(); // you need this
super.dispose();
}
@override
Widget build(BuildContext context) {
return Center(
child: Material(
color: Colors.transparent,
child: ScaleTransition(
scale: scaleAnimation,
child: Container(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
new CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>(
UtilColors.primaryColor),
),
SizedBox(
height: 10.0,
),
SizedBox(
width: Utils.displaySize.width * 0.6,
child: Text(
(Utils.loadingMessage == null)
? "Please Wait"
: Utils.loadingMessage.toString(),
textAlign: TextAlign.center,
style: GoogleFonts.nunitoSans(
color: UtilColors.whiteColor, fontSize: 12.0),
),
)
],
),
),
),
),
);
}
}
import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart';
import 'package:bloomerang/Models/Colors.dart';
import 'package:bloomerang/Models/Utils.dart';
import 'package:flutter/material.dart';
class CustomDateSelectorWithImage extends StatefulWidget {
double height = 5.0;
String hint;
var initText;
IconData icon_img;
bool isIconAvailable;
Color backgroundColor;
var onConfirm;
int type;
static int TIME_SELECTOR = 1;
static int DATE_SELECTOR = 2;
static int DATE_TIME_SELECTOR = 3;
CustomDateSelectorWithImage(
{Key? key,
required this.height,
this.initText,
required this.hint,
required this.isIconAvailable,
required this.icon_img,
required this.backgroundColor,
required this.type,
required this.onConfirm})
: super(key: key);
@override
State<CustomDateSelectorWithImage> createState() =>
_CustomDateSelectorWithImageState(
height: height,
hint: hint,
initText: initText,
type: type,
isIconAvailable: isIconAvailable,
icon_img: icon_img,
onConfirm: onConfirm,
backgroundColor: this.backgroundColor);
}
class _CustomDateSelectorWithImageState
extends State<CustomDateSelectorWithImage> {
double height = 5.0;
String hint;
var initText;
IconData icon_img;
bool isIconAvailable;
Color backgroundColor;
var onConfirm;
int type;
bool confirmed = false;
static int TIME_SELECTOR = 1;
static int DATE_SELECTOR = 2;
static int DATE_TIME_SELECTOR = 3;
String selectedText = '';
_CustomDateSelectorWithImageState(
{required this.height,
required this.hint,
required this.initText,
required this.isIconAvailable,
required this.backgroundColor,
required this.icon_img,
required this.type,
required this.onConfirm});
@override
void initState() {
initValues();
super.initState();
}
@override
Widget build(BuildContext context) {
if (initText != null && confirmed==false) {
selectedText = initText;
}
return Container(
decoration: BoxDecoration(
color: backgroundColor, borderRadius: BorderRadius.circular(5.0)),
padding: EdgeInsets.symmetric(vertical: height, horizontal: 10.0),
child: Row(
children: [
Icon(
icon_img,
color: UtilColors.primaryColor,
),
Flexible(
child: GestureDetector(
onTap: () async {
if (TIME_SELECTOR == type) {
await DatePicker.showTimePicker(context,
showTitleActions: true,
showSecondsColumn: false,
onConfirm: (time) {
confirmed = true;
onConfirm(time);
setState(() {
confirmed = true;
selectedText = Utils.formatTime(time);
});
}, onChanged: (time) {
setState(() {
confirmed = true;
selectedText = Utils.formatTime(time);
});
}, currentTime: DateTime.now(), locale: LocaleType.en);
} else if (DATE_TIME_SELECTOR == type) {
await DatePicker.showDateTimePicker(context,
showTitleActions: true,
onConfirm: (time) {
onConfirm(time);
setState(() {
confirmed = true;
selectedText = Utils.formatDateTime(time);
});
}, onChanged: (time) {
setState(() {
confirmed = true;
selectedText = Utils.formatDateTime(time);
});
}, currentTime: DateTime.now(), locale: LocaleType.en);
} else {
await DatePicker.showDatePicker(context,
showTitleActions: true,
onConfirm: (date) {
confirmed = true;
onConfirm(date);
setState(() {
selectedText = Utils.formatDate(date);
});
}, onChanged: (date) {
setState(() {
selectedText = Utils.formatDate(date);
});
}, currentTime: DateTime.now(), locale: LocaleType.en);
}
},
child: SizedBox(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
hint,
style: TextStyle(
fontFamily: 'Raleway-SemiBold',
color: UtilColors.blackColor,
fontSize: 11.0),
),
const SizedBox(
height: 5.0,
),
Text(
(confirmed == true)
? selectedText
: (initText == null)
? selectedText
: initText,
style: TextStyle(
fontFamily: 'Raleway-Medium',
color: UtilColors.blackColor,
fontSize: 15.0),
)
],
),
),
),
))
],
),
);
}
void initValues() {
setState(() {
if (TIME_SELECTOR == type) {
selectedText = Utils.formatTime(DateTime.now());
} else {
selectedText = Utils.formatDateTime(DateTime.now());
}
});
}
}
import 'dart:math';
import 'package:flutter/material.dart';
class AirDefenseSystem extends StatelessWidget {
final double radarRange;
final double enemySize;
Offset addLocation;
final _targetsPositions = <Offset>[];
final _targetsToAngage = <Offset>[];
AirDefenseSystem({
super.key,
required this.addLocation,
required this.radarRange,
required this.enemySize,
});
@override
Widget build(BuildContext context) {
print(addLocation.dx);
print(addLocation.dy);
return Container(
width: 200,
height: 200,
margin: const EdgeInsets.all(30),
child: LayoutBuilder(builder: (context, constraint) {
return AirDefenseRadar(
radarRange: radarRange,
enemySize: enemySize,
targetsToEngage: _targetsToAngage,
onScanUpdated: (radarAngle) {
final areaSize = Size(constraint.maxWidth, constraint.maxHeight);
_findAndEngageTarget(radarAngle, radarRange, areaSize);
},
onTargetAdd: (targetPosition) {
_targetsPositions.add(addLocation);
},
onTargetOutOfRange: (target) async {
// _targetsToAngage.remove(target);
},
addLocation: addLocation,
);
}),
);
}
_findAndEngageTarget(
double radarAngle, double radarRangeAreaPercentage, Size areaSize) async {
final center = areaSize.center(Offset.zero);
final radarRange = (pi * 2) / 100 * radarRangeAreaPercentage;
for (var i = 0; i < _targetsPositions.length; i++) {
final target = _targetsPositions[i];
final targetAngle = getTargetAngle(center, target);
if (isTargetInRadarRange(radarAngle, targetAngle, radarRange)) {
if (!_targetsToAngage.contains(target)) {
print('test1');
_targetsToAngage.add(target);
// _targetsPositions.remove(target);
}
}
}
}
bool isTargetInRadarRange(
double radarAngle, double targetAngle, double radarRange) {
return radarAngle >= targetAngle &&
radarAngle <= (targetAngle + radarRange);
}
double getTargetAngle(Offset center, Offset targetPosition) {
final atan2Angle = atan2(
center.dx - targetPosition.dx,
center.dy - targetPosition.dy,
);
double angle;
if (atan2Angle < 0) {
angle = atan2Angle + pi * 2;
} else {
angle = atan2Angle;
}
return (pi * 2) - angle;
}
}
class AirDefenseRadar extends StatefulWidget {
Offset addLocation;
final double radarRange;
final double enemySize;
final Function(double angle) onScanUpdated;
final Function(Offset targetLocalPosition) onTargetAdd;
final Function(Offset target) onTargetOutOfRange;
final List<Offset> targetsToEngage;
AirDefenseRadar({
Key? key,
required this.addLocation,
required this.radarRange,
required this.enemySize,
required this.onScanUpdated,
required this.onTargetAdd,
required this.onTargetOutOfRange,
this.targetsToEngage = const [],
}) : super(key: key);
@override
State<AirDefenseRadar> createState() =>
_AirDefenseRadarState(addLocation: addLocation);
}
class _AirDefenseRadarState extends State<AirDefenseRadar>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
Offset addLocation;
_AirDefenseRadarState({required this.addLocation});
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 3),
vsync: this,
);
_animation = Tween<double>(begin: 0, end: pi * 2).animate(_controller);
_controller.addStatusListener((status) {
if (status == AnimationStatus.completed) {
_controller.repeat();
}
});
_animation.addListener(() {
widget.onScanUpdated(_animation.value);
});
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
addLocationUpdate();
return Stack(
alignment: Alignment.center,
children: [
AnimatedBuilder(
animation: _animation,
builder: (context, _) {
return Stack(
children: [
Transform.rotate(
angle: _animation.value - (pi / 2),
child: CustomPaint(
size: size,
painter: AirDefenseRadarBackgroundPainter(
radarRange: widget.radarRange,
),
),
),
...widget.targetsToEngage.map(
(target) {
final enemyRadius = widget.enemySize / 2;
return Positioned(
left: target.dx - enemyRadius,
top: target.dy - enemyRadius,
child: EnemyTarget(
size: widget.enemySize,
onOutOfRange: () {
widget.onTargetOutOfRange(target);
},
),
);
},
),
],
);
},
),
CustomPaint(
size: size,
painter: AirDefenseRadarLinesPainter(),
),
],
);
}
void addLocationUpdate() {
widget.onTargetAdd(this.addLocation);
}
}
class AirDefenseRadarLinesPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
const radarColor = Color(0xFF0ef30f);
final radarLinesColor = radarColor.withOpacity(.2);
final center = size.center(Offset.zero);
final firstArcRadius = min(size.width / 2, size.height / 2);
final paint = Paint()
..color = radarLinesColor
..strokeWidth = 1
..style = PaintingStyle.stroke;
for (int i = 0; i < 5; i++) {
drawArc(canvas, center, firstArcRadius / 100 * (i * 18), paint);
}
final linePaint = Paint()
..color = radarLinesColor
..strokeWidth = 1
..style = PaintingStyle.stroke;
const outterLinesCount = 120;
const distanceFromOuterCircle = 15;
for (var i = 0; i < outterLinesCount; i++) {
final angle = i * pi / (outterLinesCount / 2);
final start = Offset(
center.dx + firstArcRadius * cos(angle),
center.dy + firstArcRadius * sin(angle),
);
final end = Offset(
center.dx + (firstArcRadius + distanceFromOuterCircle) * cos(angle),
center.dy + (firstArcRadius + distanceFromOuterCircle) * sin(angle),
);
canvas.drawLine(start, end, linePaint);
}
const crossLinesCount = 4;
for (var i = 0; i < crossLinesCount; i++) {
final angle = i * pi / (crossLinesCount / 2);
final x = center.dx + firstArcRadius * cos(angle);
final y = center.dy + firstArcRadius * sin(angle);
canvas.drawLine(center, Offset(x, y), paint);
}
}
void drawArc(
Canvas canvas,
Offset center,
double firstArcRadius,
Paint paint,
) {
canvas.drawArc(
Rect.fromCircle(center: center, radius: firstArcRadius),
0,
2 * pi,
false,
paint,
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
class AirDefenseRadarBackgroundPainter extends CustomPainter {
final double radarRange;
const AirDefenseRadarBackgroundPainter({
required this.radarRange,
});
@override
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
final radius = min(size.width / 2, size.height / 2);
final radialPaint = Paint()
..shader = SweepGradient(
center: Alignment.center,
startAngle: 0,
endAngle: pi * 2,
colors: const [
Colors.black,
Color(0xFF255C25),
Color(0xFF0ef30f),
],
stops: [
0,
1 - (radarRange / 100),
1,
],
).createShader(Rect.fromCircle(center: center, radius: radius));
canvas.drawCircle(center, radius / 100 * 90, radialPaint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
class EnemyTarget extends StatefulWidget {
final double size;
final VoidCallback onOutOfRange;
const EnemyTarget({
Key? key,
required this.size,
required this.onOutOfRange,
}) : super(key: key);
@override
State<EnemyTarget> createState() => _EnemyTargetState();
}
class _EnemyTargetState extends State<EnemyTarget>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 4),
vsync: this,
);
_animation = Tween<double>(begin: 0, end: 1).animate(_controller);
_controller.addStatusListener((status) {
if (status == AnimationStatus.completed) {
widget.onOutOfRange();
}
});
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (context, _) {
return Opacity(
opacity: 1,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
gradient: RadialGradient(
center: Alignment.center,
radius: 1,
stops: const [
0,
0.3,
.5,
],
colors: [
Color.fromARGB(255, 243, 0, 41),
Color.fromARGB(255, 218, 41, 41).withOpacity(.2),
Color.fromARGB(255, 175, 76, 76).withOpacity(0),
],
),
),
width: widget.size,
height: widget.size,
),
);
},
);
}
}
// File generated by FlutterFire CLI.
// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
return web;
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
return macos;
case TargetPlatform.windows:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for windows - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}
static const FirebaseOptions web = FirebaseOptions(
apiKey: 'AIzaSyBf3T8Bm21uWx_KQ-9QcncYaP60tr1Td5o',
appId: '1:812696838330:web:f1a9806f00048dff80a283',
messagingSenderId: '812696838330',
projectId: 'plantation-flower',
authDomain: 'plantation-flower.firebaseapp.com',
databaseURL: 'https://plantation-flower-default-rtdb.firebaseio.com',
storageBucket: 'plantation-flower.appspot.com',
measurementId: 'G-257FKRY3KN',
);
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyCXnGqsBvuJhrycdLHRpXQgi_Oxs3FWywI',
appId: '1:812696838330:android:280379d145581a4080a283',
messagingSenderId: '812696838330',
projectId: 'plantation-flower',
databaseURL: 'https://plantation-flower-default-rtdb.firebaseio.com',
storageBucket: 'plantation-flower.appspot.com',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyDGlXlytc4Mzz62RjznIzU2vifjgZq1TXI',
appId: '1:812696838330:ios:da8105f2853dd15d80a283',
messagingSenderId: '812696838330',
projectId: 'plantation-flower',
databaseURL: 'https://plantation-flower-default-rtdb.firebaseio.com',
storageBucket: 'plantation-flower.appspot.com',
iosClientId: '812696838330-bat5abifnegpjb02rdjpinhoh6updgqn.apps.googleusercontent.com',
iosBundleId: 'com.aries.bloomerang',
);
static const FirebaseOptions macos = FirebaseOptions(
apiKey: 'AIzaSyDGlXlytc4Mzz62RjznIzU2vifjgZq1TXI',
appId: '1:812696838330:ios:da8105f2853dd15d80a283',
messagingSenderId: '812696838330',
projectId: 'plantation-flower',
databaseURL: 'https://plantation-flower-default-rtdb.firebaseio.com',
storageBucket: 'plantation-flower.appspot.com',
iosClientId: '812696838330-bat5abifnegpjb02rdjpinhoh6updgqn.apps.googleusercontent.com',
iosBundleId: 'com.aries.bloomerang',
);
}
// import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:bloomerang/Views/Common/SplashScreen.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'Models/Colors.dart';
import 'firebase_options.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
initializeNotifications();
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
runApp(MyApp());
}
void initializeNotifications() {
AwesomeNotifications().initialize(
'resource://drawable/res_app_icon',
[
NotificationChannel(
channelGroupKey: 'emergency_bloomerang_group',
channelKey: 'emergency_bloomerang',
channelName: 'Bloomerang notifications',
channelDescription: 'Notification from bloomerang',
defaultColor: UtilColors.primaryColor,
ledColor: UtilColors.whiteColor)
],
channelGroups: [
NotificationChannelGroup(
channelGroupkey: 'emergency_bloomerang_group',
channelGroupName: 'Bloomerang group')
],
debug: true);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(),
title: 'Bloomerang',
home: const Scaffold(
body: SplashScreen(),
),
);
}
}
flutter/ephemeral
# Project-level configuration.
cmake_minimum_required(VERSION 3.10)
project(runner LANGUAGES CXX)
# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
set(BINARY_NAME "fishtank")
# The unique GTK application identifier for this application. See:
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
set(APPLICATION_ID "com.aries.bloomerang")
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake.
cmake_policy(SET CMP0063 NEW)
# Load bundled libraries from the lib/ directory relative to the binary.
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
# Root filesystem for cross-building.
if(FLUTTER_TARGET_PLATFORM_SYSROOT)
set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endif()
# Define build configuration options.
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Debug" CACHE
STRING "Flutter build mode" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Profile" "Release")
endif()
# Compilation settings that should be applied to most targets.
#
# Be cautious about adding new options here, as plugins use this function by
# default. In most cases, you should add new options to specific targets instead
# of modifying this function.
function(APPLY_STANDARD_SETTINGS TARGET)
target_compile_features(${TARGET} PUBLIC cxx_std_14)
target_compile_options(${TARGET} PRIVATE -Wall -Werror)
target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
endfunction()
# Flutter library and tool build rules.
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
add_subdirectory(${FLUTTER_MANAGED_DIR})
# System-level dependencies.
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
# Define the application target. To change its name, change BINARY_NAME above,
# not the value here, or `flutter run` will no longer work.
#
# Any new source files that you add to the application should be added here.
add_executable(${BINARY_NAME}
"main.cc"
"my_application.cc"
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
)
# Apply the standard set of build settings. This can be removed for applications
# that need different build settings.
apply_standard_settings(${BINARY_NAME})
# Add dependency libraries. Add any application-specific dependencies here.
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
# Run the Flutter tool portions of the build. This must not be removed.
add_dependencies(${BINARY_NAME} flutter_assemble)
# Only the install-generated bundle's copy of the executable will launch
# correctly, since the resources must in the right relative locations. To avoid
# people trying to run the unbundled copy, put it in a subdirectory instead of
# the default top-level location.
set_target_properties(${BINARY_NAME}
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
)
# Generated plugin build rules, which manage building the plugins and adding
# them to the application.
include(flutter/generated_plugins.cmake)
# === Installation ===
# By default, "installing" just makes a relocatable bundle in the build
# directory.
set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
endif()
# Start with a clean build bundle directory every time.
install(CODE "
file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
" COMPONENT Runtime)
set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
COMPONENT Runtime)
install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
COMPONENT Runtime)
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
install(FILES "${bundled_library}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endforeach(bundled_library)
# Fully re-copy the assets directory on each build to avoid having stale files
# from a previous install.
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
install(CODE "
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
" COMPONENT Runtime)
install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
# Install the AOT library on non-Debug builds only.
if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endif()
# This file controls Flutter-level build steps. It should not be edited.
cmake_minimum_required(VERSION 3.10)
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
# Configuration provided via flutter tool.
include(${EPHEMERAL_DIR}/generated_config.cmake)
# TODO: Move the rest of this into files in ephemeral. See
# https://github.com/flutter/flutter/issues/57146.
# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
# which isn't available in 3.10.
function(list_prepend LIST_NAME PREFIX)
set(NEW_LIST "")
foreach(element ${${LIST_NAME}})
list(APPEND NEW_LIST "${PREFIX}${element}")
endforeach(element)
set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
endfunction()
# === Flutter Library ===
# System-level dependencies.
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
# Published to parent scope for install step.
set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
list(APPEND FLUTTER_LIBRARY_HEADERS
"fl_basic_message_channel.h"
"fl_binary_codec.h"
"fl_binary_messenger.h"
"fl_dart_project.h"
"fl_engine.h"
"fl_json_message_codec.h"
"fl_json_method_codec.h"
"fl_message_codec.h"
"fl_method_call.h"
"fl_method_channel.h"
"fl_method_codec.h"
"fl_method_response.h"
"fl_plugin_registrar.h"
"fl_plugin_registry.h"
"fl_standard_message_codec.h"
"fl_standard_method_codec.h"
"fl_string_codec.h"
"fl_value.h"
"fl_view.h"
"flutter_linux.h"
)
list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
add_library(flutter INTERFACE)
target_include_directories(flutter INTERFACE
"${EPHEMERAL_DIR}"
)
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
target_link_libraries(flutter INTERFACE
PkgConfig::GTK
PkgConfig::GLIB
PkgConfig::GIO
)
add_dependencies(flutter flutter_assemble)
# === Flutter tool backend ===
# _phony_ is a non-existent file to force this command to run every time,
# since currently there's no way to get a full input/output list from the
# flutter tool.
add_custom_command(
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
${CMAKE_CURRENT_BINARY_DIR}/_phony_
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
VERBATIM
)
add_custom_target(flutter_assemble DEPENDS
"${FLUTTER_LIBRARY}"
${FLUTTER_LIBRARY_HEADERS}
)
//
// Generated file. Do not edit.
//
// clang-format off
#include "generated_plugin_registrant.h"
#include <file_selector_linux/file_selector_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
}
//
// Generated file. Do not edit.
//
// clang-format off
#ifndef GENERATED_PLUGIN_REGISTRANT_
#define GENERATED_PLUGIN_REGISTRANT_
#include <flutter_linux/flutter_linux.h>
// Registers Flutter plugins.
void fl_register_plugins(FlPluginRegistry* registry);
#endif // GENERATED_PLUGIN_REGISTRANT_
#
# Generated file, do not edit.
#
list(APPEND FLUTTER_PLUGIN_LIST
file_selector_linux
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
)
set(PLUGIN_BUNDLED_LIBRARIES)
foreach(plugin ${FLUTTER_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
endforeach(plugin)
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
endforeach(ffi_plugin)
#include "my_application.h"
int main(int argc, char** argv) {
g_autoptr(MyApplication) app = my_application_new();
return g_application_run(G_APPLICATION(app), argc, argv);
}
#include "my_application.h"
#include <flutter_linux/flutter_linux.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#endif
#include "flutter/generated_plugin_registrant.h"
struct _MyApplication {
GtkApplication parent_instance;
char** dart_entrypoint_arguments;
};
G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
// Implements GApplication::activate.
static void my_application_activate(GApplication* application) {
MyApplication* self = MY_APPLICATION(application);
GtkWindow* window =
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
// Use a header bar when running in GNOME as this is the common style used
// by applications and is the setup most users will be using (e.g. Ubuntu
// desktop).
// If running on X and not using GNOME then just use a traditional title bar
// in case the window manager does more exotic layout, e.g. tiling.
// If running on Wayland assume the header bar will work (may need changing
// if future cases occur).
gboolean use_header_bar = TRUE;
#ifdef GDK_WINDOWING_X11
GdkScreen* screen = gtk_window_get_screen(window);
if (GDK_IS_X11_SCREEN(screen)) {
const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
use_header_bar = FALSE;
}
}
#endif
if (use_header_bar) {
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_widget_show(GTK_WIDGET(header_bar));
gtk_header_bar_set_title(header_bar, "fishtank");
gtk_header_bar_set_show_close_button(header_bar, TRUE);
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
} else {
gtk_window_set_title(window, "fishtank");
}
gtk_window_set_default_size(window, 1280, 720);
gtk_widget_show(GTK_WIDGET(window));
g_autoptr(FlDartProject) project = fl_dart_project_new();
fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
FlView* view = fl_view_new(project);
gtk_widget_show(GTK_WIDGET(view));
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
fl_register_plugins(FL_PLUGIN_REGISTRY(view));
gtk_widget_grab_focus(GTK_WIDGET(view));
}
// Implements GApplication::local_command_line.
static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) {
MyApplication* self = MY_APPLICATION(application);
// Strip out the first argument as it is the binary name.
self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
g_autoptr(GError) error = nullptr;
if (!g_application_register(application, nullptr, &error)) {
g_warning("Failed to register: %s", error->message);
*exit_status = 1;
return TRUE;
}
g_application_activate(application);
*exit_status = 0;
return TRUE;
}
// Implements GObject::dispose.
static void my_application_dispose(GObject* object) {
MyApplication* self = MY_APPLICATION(object);
g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
}
static void my_application_class_init(MyApplicationClass* klass) {
G_APPLICATION_CLASS(klass)->activate = my_application_activate;
G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
}
static void my_application_init(MyApplication* self) {}
MyApplication* my_application_new() {
return MY_APPLICATION(g_object_new(my_application_get_type(),
"application-id", APPLICATION_ID,
"flags", G_APPLICATION_NON_UNIQUE,
nullptr));
}
#ifndef FLUTTER_MY_APPLICATION_H_
#define FLUTTER_MY_APPLICATION_H_
#include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
GtkApplication)
/**
* my_application_new:
*
* Creates a new Flutter-based application.
*
* Returns: a new #MyApplication.
*/
MyApplication* my_application_new();
#endif // FLUTTER_MY_APPLICATION_H_
# Flutter-related
**/Flutter/ephemeral/
**/Pods/
# Xcode-related
**/dgph
**/xcuserdata/
#include "ephemeral/Flutter-Generated.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig"
//
// Generated file. Do not edit.
//
import FlutterMacOS
import Foundation
import file_selector_macos
import firebase_auth
import firebase_core
import firebase_database
import path_provider_foundation
import sqflite
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin"))
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
FLTFirebaseDatabasePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseDatabasePlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
}
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objects = {
/* Begin PBXAggregateTarget section */
33CC111A2044C6BA0003C045 /* Flutter Assemble */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */;
buildPhases = (
33CC111E2044C6BF0003C045 /* ShellScript */,
);
dependencies = (
);
name = "Flutter Assemble";
productName = FLX;
};
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 33CC111A2044C6BA0003C045;
remoteInfo = FLX;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
33CC110E2044A8840003C045 /* Bundle Framework */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Bundle Framework";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
33CC10ED2044A3C60003C045 /* fishtank.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "fishtank.app"; sourceTree = BUILT_PRODUCTS_DIR; };
33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = "<group>"; };
33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = "<group>"; };
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = "<group>"; };
33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = "<group>"; };
33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = "<group>"; };
33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
33CC10EA2044A3C60003C045 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
33BA886A226E78AF003329D5 /* Configs */ = {
isa = PBXGroup;
children = (
33E5194F232828860026EE4D /* AppInfo.xcconfig */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
333000ED22D3DE5D00554162 /* Warnings.xcconfig */,
);
path = Configs;
sourceTree = "<group>";
};
33CC10E42044A3C60003C045 = {
isa = PBXGroup;
children = (
33FAB671232836740065AC1E /* Runner */,
33CEB47122A05771004F2AC0 /* Flutter */,
33CC10EE2044A3C60003C045 /* Products */,
D73912EC22F37F3D000D13A0 /* Frameworks */,
);
sourceTree = "<group>";
};
33CC10EE2044A3C60003C045 /* Products */ = {
isa = PBXGroup;
children = (
33CC10ED2044A3C60003C045 /* fishtank.app */,
);
name = Products;
sourceTree = "<group>";
};
33CC11242044D66E0003C045 /* Resources */ = {
isa = PBXGroup;
children = (
33CC10F22044A3C60003C045 /* Assets.xcassets */,
33CC10F42044A3C60003C045 /* MainMenu.xib */,
33CC10F72044A3C60003C045 /* Info.plist */,
);
name = Resources;
path = ..;
sourceTree = "<group>";
};
33CEB47122A05771004F2AC0 /* Flutter */ = {
isa = PBXGroup;
children = (
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */,
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,
33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,
);
path = Flutter;
sourceTree = "<group>";
};
33FAB671232836740065AC1E /* Runner */ = {
isa = PBXGroup;
children = (
33CC10F02044A3C60003C045 /* AppDelegate.swift */,
33CC11122044BFA00003C045 /* MainFlutterWindow.swift */,
33E51913231747F40026EE4D /* DebugProfile.entitlements */,
33E51914231749380026EE4D /* Release.entitlements */,
33CC11242044D66E0003C045 /* Resources */,
33BA886A226E78AF003329D5 /* Configs */,
);
path = Runner;
sourceTree = "<group>";
};
D73912EC22F37F3D000D13A0 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
33CC10EC2044A3C60003C045 /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
33CC10E92044A3C60003C045 /* Sources */,
33CC10EA2044A3C60003C045 /* Frameworks */,
33CC10EB2044A3C60003C045 /* Resources */,
33CC110E2044A8840003C045 /* Bundle Framework */,
3399D490228B24CF009A79C7 /* ShellScript */,
);
buildRules = (
);
dependencies = (
33CC11202044C79F0003C045 /* PBXTargetDependency */,
);
name = Runner;
productName = Runner;
productReference = 33CC10ED2044A3C60003C045 /* fishtank.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
33CC10E52044A3C60003C045 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0920;
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
33CC10EC2044A3C60003C045 = {
CreatedOnToolsVersion = 9.2;
LastSwiftMigration = 1100;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.Sandbox = {
enabled = 1;
};
};
};
33CC111A2044C6BA0003C045 = {
CreatedOnToolsVersion = 9.2;
ProvisioningStyle = Manual;
};
};
};
buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 33CC10E42044A3C60003C045;
productRefGroup = 33CC10EE2044A3C60003C045 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
33CC10EC2044A3C60003C045 /* Runner */,
33CC111A2044C6BA0003C045 /* Flutter Assemble */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
33CC10EB2044A3C60003C045 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3399D490228B24CF009A79C7 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n";
};
33CC111E2044C6BF0003C045 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
Flutter/ephemeral/FlutterInputs.xcfilelist,
);
inputPaths = (
Flutter/ephemeral/tripwire,
);
outputFileListPaths = (
Flutter/ephemeral/FlutterOutputs.xcfilelist,
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
33CC10E92044A3C60003C045 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */,
33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */,
335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
33CC11202044C79F0003C045 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */;
targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
33CC10F42044A3C60003C045 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
33CC10F52044A3C60003C045 /* Base */,
);
name = MainMenu.xib;
path = Runner;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
338D0CE9231458BD00FA5F75 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
};
name = Profile;
};
338D0CEA231458BD00FA5F75 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
};
name = Profile;
};
338D0CEB231458BD00FA5F75 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Manual;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Profile;
};
33CC10F92044A3C60003C045 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
33CC10FA2044A3C60003C045 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
};
name = Release;
};
33CC10FC2044A3C60003C045 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
};
name = Debug;
};
33CC10FD2044A3C60003C045 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
};
name = Release;
};
33CC111C2044C6BA0003C045 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Manual;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
33CC111D2044C6BA0003C045 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
33CC10F92044A3C60003C045 /* Debug */,
33CC10FA2044A3C60003C045 /* Release */,
338D0CE9231458BD00FA5F75 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
33CC10FC2044A3C60003C045 /* Debug */,
33CC10FD2044A3C60003C045 /* Release */,
338D0CEA231458BD00FA5F75 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = {
isa = XCConfigurationList;
buildConfigurations = (
33CC111C2044C6BA0003C045 /* Debug */,
33CC111D2044C6BA0003C045 /* Release */,
338D0CEB231458BD00FA5F75 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 33CC10E52044A3C60003C045 /* Project object */;
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "fishtank.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "fishtank.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "fishtank.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "fishtank.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
import Cocoa
import FlutterMacOS
@NSApplicationMain
class AppDelegate: FlutterAppDelegate {
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}
}
{
"images" : [
{
"size" : "16x16",
"idiom" : "mac",
"filename" : "app_icon_16.png",
"scale" : "1x"
},
{
"size" : "16x16",
"idiom" : "mac",
"filename" : "app_icon_32.png",
"scale" : "2x"
},
{
"size" : "32x32",
"idiom" : "mac",
"filename" : "app_icon_32.png",
"scale" : "1x"
},
{
"size" : "32x32",
"idiom" : "mac",
"filename" : "app_icon_64.png",
"scale" : "2x"
},
{
"size" : "128x128",
"idiom" : "mac",
"filename" : "app_icon_128.png",
"scale" : "1x"
},
{
"size" : "128x128",
"idiom" : "mac",
"filename" : "app_icon_256.png",
"scale" : "2x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "app_icon_256.png",
"scale" : "1x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "app_icon_512.png",
"scale" : "2x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "app_icon_512.png",
"scale" : "1x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "app_icon_1024.png",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="Runner" customModuleProvider="target">
<connections>
<outlet property="applicationMenu" destination="uQy-DD-JDr" id="XBo-yE-nKs"/>
<outlet property="mainFlutterWindow" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
<menuItem title="APP_NAME" id="1Xt-HY-uBw">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="APP_NAME" systemMenu="apple" id="uQy-DD-JDr">
<items>
<menuItem title="About APP_NAME" id="5kV-Vb-QxS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
<menuItem title="Services" id="NMo-om-nkz">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
<menuItem title="Hide APP_NAME" keyEquivalent="h" id="Olw-nP-bQN">
<connections>
<action selector="hide:" target="-1" id="PnN-Uc-m68"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
</connections>
</menuItem>
<menuItem title="Show All" id="Kd2-mp-pUS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
<menuItem title="Quit APP_NAME" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Edit" id="5QF-Oa-p0T">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
<items>
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
<connections>
<action selector="undo:" target="-1" id="M6e-cu-g7V"/>
</connections>
</menuItem>
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
<connections>
<action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
<connections>
<action selector="cut:" target="-1" id="YJe-68-I9s"/>
</connections>
</menuItem>
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
<connections>
<action selector="copy:" target="-1" id="G1f-GL-Joy"/>
</connections>
</menuItem>
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
<connections>
<action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
</connections>
</menuItem>
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
</connections>
</menuItem>
<menuItem title="Delete" id="pa3-QI-u2k">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
</connections>
</menuItem>
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
<connections>
<action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
<menuItem title="Find" id="4EN-yA-p0u">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Find" id="1b7-l0-nxx">
<items>
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
<connections>
<action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
</connections>
</menuItem>
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
</connections>
</menuItem>
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
<connections>
<action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
</connections>
</menuItem>
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
<connections>
<action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
</connections>
</menuItem>
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
<connections>
<action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
</connections>
</menuItem>
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
<connections>
<action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
<items>
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
<connections>
<action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
</connections>
</menuItem>
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
<connections>
<action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
</connections>
</menuItem>
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
</connections>
</menuItem>
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Substitutions" id="9ic-FL-obx">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
<items>
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
</connections>
</menuItem>
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
</connections>
</menuItem>
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
</connections>
</menuItem>
<menuItem title="Smart Links" id="cwL-P1-jid">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
</connections>
</menuItem>
<menuItem title="Data Detectors" id="tRr-pd-1PS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
</connections>
</menuItem>
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Transformations" id="2oI-Rn-ZJC">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
<items>
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
</connections>
</menuItem>
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
</connections>
</menuItem>
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Speech" id="xrE-MZ-jX0">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
<items>
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
</connections>
</menuItem>
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="View" id="H8h-7b-M4v">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="View" id="HyV-fh-RgO">
<items>
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="toggleFullScreen:" target="-1" id="dU3-MA-1Rq"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="aUF-d1-5bR">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
<connections>
<action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="R4o-n2-Eq4">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="EPT-qC-fAb">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Help" systemMenu="help" id="rJ0-wn-3NY"/>
</menuItem>
</items>
<point key="canvasLocation" x="142" y="-258"/>
</menu>
<window title="APP_NAME" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="MainFlutterWindow" customModule="Runner" customModuleProvider="target">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<rect key="contentRect" x="335" y="390" width="800" height="600"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1577"/>
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
<rect key="frame" x="0.0" y="0.0" width="800" height="600"/>
<autoresizingMask key="autoresizingMask"/>
</view>
</window>
</objects>
</document>
// Application-level settings for the Runner target.
//
// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
// future. If not, the values below would default to using the project name when this becomes a
// 'flutter create' template.
// The application's name. By default this is also the title of the Flutter window.
PRODUCT_NAME = fishtank
// The application's bundle identifier
PRODUCT_BUNDLE_IDENTIFIER = com.aries.bloomerang
// The copyright displayed in application information
PRODUCT_COPYRIGHT = Copyright © 2022 com.example. All rights reserved.
#include "../../Flutter/Flutter-Debug.xcconfig"
#include "Warnings.xcconfig"
#include "../../Flutter/Flutter-Release.xcconfig"
#include "Warnings.xcconfig"
WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings
GCC_WARN_UNDECLARED_SELECTOR = YES
CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
CLANG_WARN_PRAGMA_PACK = YES
CLANG_WARN_STRICT_PROTOTYPES = YES
CLANG_WARN_COMMA = YES
GCC_WARN_STRICT_SELECTOR_MATCH = YES
CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
GCC_WARN_SHADOW = YES
CLANG_WARN_UNREACHABLE_CODE = YES
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>950483741203-r767t7704p8536e0sa3qooqh9sihvt8d.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.950483741203-r767t7704p8536e0sa3qooqh9sihvt8d</string>
<key>API_KEY</key>
<string>AIzaSyDRHIH0b_PQ4Bfu_31oF7tpgkO7Tgj-Az0</string>
<key>GCM_SENDER_ID</key>
<string>950483741203</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.aries.bloomerang</string>
<key>PROJECT_ID</key>
<string>fish-tank-7907f</string>
<key>STORAGE_BUCKET</key>
<string>fish-tank-7907f.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:950483741203:ios:1e1e5eb1a8cf63e0cc6de6</string>
<key>DATABASE_URL</key>
<string>https://fish-tank-7907f-default-rtdb.firebaseio.com</string>
</dict>
</plist>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
<string>$(PRODUCT_COPYRIGHT)</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>
import Cocoa
import FlutterMacOS
class MainFlutterWindow: NSWindow {
override func awakeFromNib() {
let flutterViewController = FlutterViewController.init()
let windowFrame = self.frame
self.contentViewController = flutterViewController
self.setFrame(windowFrame, display: true)
RegisterGeneratedPlugins(registry: flutterViewController)
super.awakeFromNib()
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
</dict>
</plist>
{
"file_generated_by": "FlutterFire CLI",
"purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory",
"GOOGLE_APP_ID": "1:812696838330:ios:da8105f2853dd15d80a283",
"FIREBASE_PROJECT_ID": "plantation-flower",
"GCM_SENDER_ID": "812696838330"
}
\ No newline at end of file
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
_flutterfire_internals:
dependency: transitive
description:
name: _flutterfire_internals
sha256: "1a5e13736d59235ce0139621b4bbe29bc89839e202409081bc667eb3cd20674c"
url: "https://pub.dev"
source: hosted
version: "1.3.5"
animate_do:
dependency: "direct main"
description:
name: animate_do
sha256: "9aeacc1a7238f971c039bdf45d13c628be554a242e0251c4ddda09d19a1a923f"
url: "https://pub.dev"
source: hosted
version: "3.0.2"
archive:
dependency: transitive
description:
name: archive
sha256: "49b1fad315e57ab0bbc15bcbb874e83116a1d78f77ebd500a4af6c9407d6b28e"
url: "https://pub.dev"
source: hosted
version: "3.3.8"
args:
dependency: transitive
description:
name: args
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
url: "https://pub.dev"
source: hosted
version: "2.4.2"
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.11.0"
auto_size_text:
dependency: "direct main"
description:
name: auto_size_text
sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
awesome_notifications:
dependency: "direct main"
description:
name: awesome_notifications
sha256: "6482ced1a57d0cb7eaecafdeb8ac5ef8547dfd39e5e6af7b24e220b8fd888a6e"
url: "https://pub.dev"
source: hosted
version: "0.6.21"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
cached_network_image:
dependency: "direct main"
description:
name: cached_network_image
sha256: fd3d0dc1d451f9a252b32d95d3f0c3c487bc41a75eba2e6097cb0b9c71491b15
url: "https://pub.dev"
source: hosted
version: "3.2.3"
cached_network_image_platform_interface:
dependency: transitive
description:
name: cached_network_image_platform_interface
sha256: bb2b8403b4ccdc60ef5f25c70dead1f3d32d24b9d6117cfc087f496b178594a7
url: "https://pub.dev"
source: hosted
version: "2.0.0"
cached_network_image_web:
dependency: transitive
description:
name: cached_network_image_web
sha256: b8eb814ebfcb4dea049680f8c1ffb2df399e4d03bf7a352c775e26fa06e02fa0
url: "https://pub.dev"
source: hosted
version: "1.0.2"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
url: "https://pub.dev"
source: hosted
version: "2.0.3"
cli_util:
dependency: transitive
description:
name: cli_util
sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7
url: "https://pub.dev"
source: hosted
version: "0.4.0"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
version: "1.17.2"
convert:
dependency: transitive
description:
name: convert
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
cross_file:
dependency: transitive
description:
name: cross_file
sha256: fd832b5384d0d6da4f6df60b854d33accaaeb63aa9e10e736a87381f08dee2cb
url: "https://pub.dev"
source: hosted
version: "0.3.3+5"
crypto:
dependency: transitive
description:
name: crypto
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.dev"
source: hosted
version: "3.0.3"
csslib:
dependency: transitive
description:
name: csslib
sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
url: "https://pub.dev"
source: hosted
version: "1.0.6"
email_validator:
dependency: "direct main"
description:
name: email_validator
sha256: e9a90f27ab2b915a27d7f9c2a7ddda5dd752d6942616ee83529b686fc086221b
url: "https://pub.dev"
source: hosted
version: "2.1.17"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
file:
dependency: transitive
description:
name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
file_selector_linux:
dependency: transitive
description:
name: file_selector_linux
sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492"
url: "https://pub.dev"
source: hosted
version: "0.9.2+1"
file_selector_macos:
dependency: transitive
description:
name: file_selector_macos
sha256: "182c3f8350cee659f7b115e956047ee3dc672a96665883a545e81581b9a82c72"
url: "https://pub.dev"
source: hosted
version: "0.9.3+2"
file_selector_platform_interface:
dependency: transitive
description:
name: file_selector_platform_interface
sha256: "0aa47a725c346825a2bd396343ce63ac00bda6eff2fbc43eabe99737dede8262"
url: "https://pub.dev"
source: hosted
version: "2.6.1"
file_selector_windows:
dependency: transitive
description:
name: file_selector_windows
sha256: d3547240c20cabf205c7c7f01a50ecdbc413755814d6677f3cb366f04abcead0
url: "https://pub.dev"
source: hosted
version: "0.9.3+1"
firebase_auth:
dependency: "direct main"
description:
name: firebase_auth
sha256: "6d9be853426ab686d68076b8007ac29b2c31e7d549444a45b5c3fe1abc249fb0"
url: "https://pub.dev"
source: hosted
version: "4.9.0"
firebase_auth_platform_interface:
dependency: transitive
description:
name: firebase_auth_platform_interface
sha256: "2946cfdc17f925fa9771dd0ba3ce9dd2d019100a8685d0557c161f7786ea9b14"
url: "https://pub.dev"
source: hosted
version: "6.18.0"
firebase_auth_web:
dependency: transitive
description:
name: firebase_auth_web
sha256: d8972d754702a3f4881184706b8056e2837d0dae91613a43b988c960b8e0d988
url: "https://pub.dev"
source: hosted
version: "5.8.0"
firebase_core:
dependency: transitive
description:
name: firebase_core
sha256: c78132175edda4bc532a71e01a32964e4b4fcf53de7853a422d96dac3725f389
url: "https://pub.dev"
source: hosted
version: "2.15.1"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
sha256: b63e3be6c96ef5c33bdec1aab23c91eb00696f6452f0519401d640938c94cba2
url: "https://pub.dev"
source: hosted
version: "4.8.0"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
sha256: "4cf4d2161530332ddc3c562f19823fb897ff37a9a774090d28df99f47370e973"
url: "https://pub.dev"
source: hosted
version: "2.7.0"
firebase_database:
dependency: "direct main"
description:
name: firebase_database
sha256: "61d4f75599382194e5a5617e606f61ea5fe092315c61976fab9d3bd7b291e23c"
url: "https://pub.dev"
source: hosted
version: "10.2.5"
firebase_database_platform_interface:
dependency: transitive
description:
name: firebase_database_platform_interface
sha256: "951738c448a01a9aca2b72b59bf9ebd769a59e49cbae8a5b376e9bdd0ccba3de"
url: "https://pub.dev"
source: hosted
version: "0.2.5+5"
firebase_database_web:
dependency: transitive
description:
name: firebase_database_web
sha256: fcbd0fc83cabd529b88723d6721d10d7a88d10480fd93904513e60e32c5016d1
url: "https://pub.dev"
source: hosted
version: "0.2.3+5"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_blurhash:
dependency: transitive
description:
name: flutter_blurhash
sha256: "05001537bd3fac7644fa6558b09ec8c0a3f2eba78c0765f88912882b1331a5c6"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
flutter_cache_manager:
dependency: transitive
description:
name: flutter_cache_manager
sha256: "8207f27539deb83732fdda03e259349046a39a4c767269285f449ade355d54ba"
url: "https://pub.dev"
source: hosted
version: "3.3.1"
flutter_datetime_picker_plus:
dependency: "direct main"
description:
name: flutter_datetime_picker_plus
sha256: "46c01682a65d6877b40622df2ca4f13b728e5440a9c83c3992c09724bb4dbd95"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
flutter_launcher_icons:
dependency: "direct dev"
description:
name: flutter_launcher_icons
sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea"
url: "https://pub.dev"
source: hosted
version: "0.13.1"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
url: "https://pub.dev"
source: hosted
version: "2.0.3"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: f185ac890306b5779ecbd611f52502d8d4d63d27703ef73161ca0407e815f02c
url: "https://pub.dev"
source: hosted
version: "2.0.16"
flutter_radar_chart:
dependency: "direct main"
description:
name: flutter_radar_chart
sha256: c98b635de2e3f5b0b1300093023845825b616c8e523776a8a3a714c28f23f211
url: "https://pub.dev"
source: hosted
version: "0.2.1"
flutter_slidable:
dependency: "direct main"
description:
name: flutter_slidable
sha256: "90787334388211e6810065550119b015e6fd3893584641194d500bf5bc7e6235"
url: "https://pub.dev"
source: hosted
version: "1.3.2"
flutter_switch:
dependency: "direct main"
description:
name: flutter_switch
sha256: b91477f926bba135d2d203d7b24367492662d8d9c3aa6adb960b14c1087d3c41
url: "https://pub.dev"
source: hosted
version: "0.3.2"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
fluttertoast:
dependency: "direct main"
description:
name: fluttertoast
sha256: "474f7d506230897a3cd28c965ec21c5328ae5605fc9c400cd330e9e9d6ac175c"
url: "https://pub.dev"
source: hosted
version: "8.2.2"
google_fonts:
dependency: "direct main"
description:
name: google_fonts
sha256: "2776c66b3e97c6cdd58d1bd3281548b074b64f1fd5c8f82391f7456e38849567"
url: "https://pub.dev"
source: hosted
version: "4.0.5"
google_sign_in:
dependency: "direct main"
description:
name: google_sign_in
sha256: "821f354c053d51a2d417b02d42532a19a6ea8057d2f9ebb8863c07d81c98aaf9"
url: "https://pub.dev"
source: hosted
version: "5.4.4"
google_sign_in_android:
dependency: transitive
description:
name: google_sign_in_android
sha256: "8d76099cb220d4f10c7e3c24492814c733f48ecb574c45c0ccadf5d5e50b012d"
url: "https://pub.dev"
source: hosted
version: "6.1.19"
google_sign_in_ios:
dependency: transitive
description:
name: google_sign_in_ios
sha256: "8edfde9698b5951f3d02632eceb39cc283865c3cff0b03216bf951089f10345b"
url: "https://pub.dev"
source: hosted
version: "5.6.3"
google_sign_in_platform_interface:
dependency: transitive
description:
name: google_sign_in_platform_interface
sha256: "35ceee5f0eadc1c07b0b4af7553246e315c901facbb7d3dadf734ba2693ceec4"
url: "https://pub.dev"
source: hosted
version: "2.4.2"
google_sign_in_web:
dependency: transitive
description:
name: google_sign_in_web
sha256: "75cc41ebc53b1756320ee14d9c3018ad3e6cea298147dbcd86e9d0c8d6720b40"
url: "https://pub.dev"
source: hosted
version: "0.10.2+1"
html:
dependency: transitive
description:
name: html
sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a"
url: "https://pub.dev"
source: hosted
version: "0.15.4"
http:
dependency: transitive
description:
name: http
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
http_parser:
dependency: transitive
description:
name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
image:
dependency: transitive
description:
name: image
sha256: a72242c9a0ffb65d03de1b7113bc4e189686fc07c7147b8b41811d0dd0e0d9bf
url: "https://pub.dev"
source: hosted
version: "4.0.17"
image_picker:
dependency: "direct main"
description:
name: image_picker
sha256: b6951e25b795d053a6ba03af5f710069c99349de9341af95155d52665cb4607c
url: "https://pub.dev"
source: hosted
version: "0.8.9"
image_picker_android:
dependency: transitive
description:
name: image_picker_android
sha256: d32a997bcc4ee135aebca8e272b7c517927aa65a74b9c60a81a2764ef1a0462d
url: "https://pub.dev"
source: hosted
version: "0.8.7+5"
image_picker_for_web:
dependency: transitive
description:
name: image_picker_for_web
sha256: "869fe8a64771b7afbc99fc433a5f7be2fea4d1cb3d7c11a48b6b579eb9c797f0"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
image_picker_ios:
dependency: transitive
description:
name: image_picker_ios
sha256: c5538cacefacac733c724be7484377923b476216ad1ead35a0d2eadcdc0fc497
url: "https://pub.dev"
source: hosted
version: "0.8.8+2"
image_picker_linux:
dependency: transitive
description:
name: image_picker_linux
sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa"
url: "https://pub.dev"
source: hosted
version: "0.2.1+1"
image_picker_macos:
dependency: transitive
description:
name: image_picker_macos
sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62"
url: "https://pub.dev"
source: hosted
version: "0.2.1+1"
image_picker_platform_interface:
dependency: transitive
description:
name: image_picker_platform_interface
sha256: ed9b00e63977c93b0d2d2b343685bed9c324534ba5abafbb3dfbd6a780b1b514
url: "https://pub.dev"
source: hosted
version: "2.9.1"
image_picker_windows:
dependency: transitive
description:
name: image_picker_windows
sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb"
url: "https://pub.dev"
source: hosted
version: "0.2.1+1"
intl:
dependency: "direct main"
description:
name: intl
sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
url: "https://pub.dev"
source: hosted
version: "0.17.0"
js:
dependency: transitive
description:
name: js
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
source: hosted
version: "0.6.7"
json_annotation:
dependency: transitive
description:
name: json_annotation
sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
url: "https://pub.dev"
source: hosted
version: "4.8.1"
lints:
dependency: transitive
description:
name: lints
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
matcher:
dependency: transitive
description:
name: matcher
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
meta:
dependency: transitive
description:
name: meta
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
url: "https://pub.dev"
source: hosted
version: "1.9.1"
mime:
dependency: transitive
description:
name: mime
sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
url: "https://pub.dev"
source: hosted
version: "1.0.4"
octo_image:
dependency: transitive
description:
name: octo_image
sha256: "107f3ed1330006a3bea63615e81cf637433f5135a52466c7caa0e7152bca9143"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
path:
dependency: transitive
description:
name: path
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted
version: "1.8.3"
path_provider:
dependency: transitive
description:
name: path_provider
sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
url: "https://pub.dev"
source: hosted
version: "2.1.1"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
url: "https://pub.dev"
source: hosted
version: "2.3.1"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev"
source: hosted
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
url: "https://pub.dev"
source: hosted
version: "2.2.1"
percent_indicator:
dependency: "direct main"
description:
name: percent_indicator
sha256: c37099ad833a883c9d71782321cb65c3a848c21b6939b6185f0ff6640d05814c
url: "https://pub.dev"
source: hosted
version: "4.2.3"
permission_handler:
dependency: "direct main"
description:
name: permission_handler
sha256: "4356882e9abf51aa0d56e8fb886e0d6162719f2310dd71f0b8fa7f34908b128d"
url: "https://pub.dev"
source: hosted
version: "8.3.0"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
sha256: "7c6b1500385dd1d2ca61bb89e2488ca178e274a69144d26bbd65e33eae7c02a9"
url: "https://pub.dev"
source: hosted
version: "3.11.3"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
url: "https://pub.dev"
source: hosted
version: "5.4.0"
phone_number:
dependency: "direct main"
description:
name: phone_number
sha256: "8d5e58db244564e8280b28798d3db660be4073b62ed1ee5b8f27b5195eb7c8fc"
url: "https://pub.dev"
source: hosted
version: "0.12.0+2"
platform:
dependency: transitive
description:
name: platform
sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102
url: "https://pub.dev"
source: hosted
version: "3.1.2"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
url: "https://pub.dev"
source: hosted
version: "2.1.6"
pointycastle:
dependency: transitive
description:
name: pointycastle
sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
url: "https://pub.dev"
source: hosted
version: "3.7.3"
quiver:
dependency: transitive
description:
name: quiver
sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47
url: "https://pub.dev"
source: hosted
version: "3.2.1"
rxdart:
dependency: transitive
description:
name: rxdart
sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb"
url: "https://pub.dev"
source: hosted
version: "0.27.7"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
sprintf:
dependency: transitive
description:
name: sprintf
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
sqflite:
dependency: transitive
description:
name: sqflite
sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a"
url: "https://pub.dev"
source: hosted
version: "2.3.0"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
sha256: "1b92f368f44b0dee2425bb861cfa17b6f6cf3961f762ff6f941d20b33355660a"
url: "https://pub.dev"
source: hosted
version: "2.5.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
source: hosted
version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
syncfusion_flutter_charts:
dependency: "direct main"
description:
name: syncfusion_flutter_charts
sha256: "0222ac9d8cb6c671f014effe9bd5c0aef35eadb16471355345ba87cc0ac007b3"
url: "https://pub.dev"
source: hosted
version: "20.4.54"
syncfusion_flutter_core:
dependency: transitive
description:
name: syncfusion_flutter_core
sha256: "3979f0b1c5a97422cadae52d476c21fa3e0fb671ef51de6cae1d646d8b99fe1f"
url: "https://pub.dev"
source: hosted
version: "20.4.54"
syncfusion_flutter_gauges:
dependency: "direct main"
description:
name: syncfusion_flutter_gauges
sha256: "6b7a901a33345511080d74770dfcdc37d30a15667c73819932786b95b3ec2dfb"
url: "https://pub.dev"
source: hosted
version: "20.4.54"
synchronized:
dependency: transitive
description:
name: synchronized
sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev"
source: hosted
version: "0.6.0"
toggle_switch:
dependency: "direct main"
description:
name: toggle_switch
sha256: "3814548f25ee11f88d3b1905e2e7c8e47e4a406752f553ed287f6d86a2dcf91d"
url: "https://pub.dev"
source: hosted
version: "1.4.0"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.2"
uuid:
dependency: transitive
description:
name: uuid
sha256: e03928880bdbcbf496fb415573f5ab7b1ea99b9b04f669c01104d085893c3134
url: "https://pub.dev"
source: hosted
version: "4.0.0"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
video_player:
dependency: "direct main"
description:
name: video_player
sha256: d3910a8cefc0de8a432a4411dcf85030e885d8fef3ddea291f162253a05dbf01
url: "https://pub.dev"
source: hosted
version: "2.7.1"
video_player_android:
dependency: transitive
description:
name: video_player_android
sha256: "3fe89ab07fdbce786e7eb25b58532d6eaf189ceddc091cb66cba712f8d9e8e55"
url: "https://pub.dev"
source: hosted
version: "2.4.10"
video_player_avfoundation:
dependency: transitive
description:
name: video_player_avfoundation
sha256: c3b123a5a56c9812b9029f840c65b92fd65083eb08d69be016b01e8aa018f77d
url: "https://pub.dev"
source: hosted
version: "2.4.10"
video_player_platform_interface:
dependency: transitive
description:
name: video_player_platform_interface
sha256: be72301bf2c0150ab35a8c34d66e5a99de525f6de1e8d27c0672b836fe48f73a
url: "https://pub.dev"
source: hosted
version: "6.2.1"
video_player_web:
dependency: transitive
description:
name: video_player_web
sha256: "68bdd115389d68aea99466259b079a5ef3fa9ca7600ef12b616d8551fa1541a9"
url: "https://pub.dev"
source: hosted
version: "2.0.18"
web:
dependency: transitive
description:
name: web
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
url: "https://pub.dev"
source: hosted
version: "0.1.4-beta"
win32:
dependency: transitive
description:
name: win32
sha256: "9e82a402b7f3d518fb9c02d0e9ae45952df31b9bf34d77baf19da2de03fc2aaa"
url: "https://pub.dev"
source: hosted
version: "5.0.7"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2"
url: "https://pub.dev"
source: hosted
version: "1.0.3"
xml:
dependency: transitive
description:
name: xml
sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
url: "https://pub.dev"
source: hosted
version: "6.3.0"
yaml:
dependency: transitive
description:
name: yaml
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.1.0 <4.0.0"
flutter: ">=3.13.0"
name: bloomerang
description: A new Flutter project.
publish_to: 'none'
version: 1.0.0+1
environment:
sdk: '>=2.18.2 <3.0.0'
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
fluttertoast: ^8.0.8
email_validator: ^2.0.1
cached_network_image: ^3.2.0
permission_handler: ^8.3.0
google_sign_in: ^5.2.3
percent_indicator: ^4.0.0
flutter_slidable: ^1.2.0
auto_size_text: ^3.0.0
toggle_switch: ^1.4.0
phone_number: ^0.12.0+1
intl: ^0.17.0
syncfusion_flutter_gauges: ^20.3.47
syncfusion_flutter_charts: ^20.3.50
flutter_datetime_picker_plus: ^2.0.1
flutter_switch: ^0.3.2
awesome_notifications: ^0.6.21
image_picker: ^0.8.5+3
flutter_radar_chart: ^0.2.1
google_fonts: ^4.0.4
firebase_database: ^10.2.3
firebase_auth: ^4.6.3
video_player: ^2.6.1
animate_do: ^3.0.2
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
flutter_launcher_icons: ^0.13.1
flutter_launcher_icons:
android: "launcher_icon"
ios: true
image_path: "assets/img/logo.png"
flutter:
uses-material-design: true
assets:
- assets/img/logo.png
- assets/img/bg.png
- assets/img/user_sample.png
- assets/videos/login.mp4
<!DOCTYPE html>
<html>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.
The path provided below has to start and end with a slash "/" in order for
it to work correctly.
For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`.
-->
<base href="$FLUTTER_BASE_HREF">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="fishtank">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>
<title>fishtank</title>
<link rel="manifest" href="manifest.json">
<script>
// The value below is injected by flutter build, do not touch.
var serviceWorkerVersion = null;
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>
</head>
<body>
<script>
window.addEventListener('load', function(ev) {
// Download main.dart.js
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
}
}).then(function(engineInitializer) {
return engineInitializer.initializeEngine();
}).then(function(appRunner) {
return appRunner.runApp();
});
});
</script>
</body>
</html>
{
"name": "fishtank",
"short_name": "fishtank",
"start_url": ".",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"description": "A new Flutter project.",
"orientation": "portrait-primary",
"prefer_related_applications": false,
"icons": [
{
"src": "icons/Icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/Icon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "icons/Icon-maskable-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "icons/Icon-maskable-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}
flutter/ephemeral/
# Visual Studio user-specific files.
*.suo
*.user
*.userosscache
*.sln.docstates
# Visual Studio build-related files.
x64/
x86/
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Project-level configuration.
cmake_minimum_required(VERSION 3.14)
project(fishtank LANGUAGES CXX)
# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
set(BINARY_NAME "fishtank")
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake.
cmake_policy(SET CMP0063 NEW)
# Define build configuration option.
get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(IS_MULTICONFIG)
set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release"
CACHE STRING "" FORCE)
else()
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Debug" CACHE
STRING "Flutter build mode" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Profile" "Release")
endif()
endif()
# Define settings for the Profile build mode.
set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}")
set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}")
# Use Unicode for all projects.
add_definitions(-DUNICODE -D_UNICODE)
# Compilation settings that should be applied to most targets.
#
# Be cautious about adding new options here, as plugins use this function by
# default. In most cases, you should add new options to specific targets instead
# of modifying this function.
function(APPLY_STANDARD_SETTINGS TARGET)
target_compile_features(${TARGET} PUBLIC cxx_std_17)
target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")
target_compile_options(${TARGET} PRIVATE /EHsc)
target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0")
target_compile_definitions(${TARGET} PRIVATE "$<$<CONFIG:Debug>:_DEBUG>")
endfunction()
# Flutter library and tool build rules.
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
add_subdirectory(${FLUTTER_MANAGED_DIR})
# Application build; see runner/CMakeLists.txt.
add_subdirectory("runner")
# Generated plugin build rules, which manage building the plugins and adding
# them to the application.
include(flutter/generated_plugins.cmake)
# === Installation ===
# Support files are copied into place next to the executable, so that it can
# run in place. This is done instead of making a separate bundle (as on Linux)
# so that building and running from within Visual Studio will work.
set(BUILD_BUNDLE_DIR "$<TARGET_FILE_DIR:${BINARY_NAME}>")
# Make the "install" step default, as it's required to run.
set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
endif()
set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}")
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
COMPONENT Runtime)
install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
COMPONENT Runtime)
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
if(PLUGIN_BUNDLED_LIBRARIES)
install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endif()
# Fully re-copy the assets directory on each build to avoid having stale files
# from a previous install.
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
install(CODE "
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
" COMPONENT Runtime)
install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
# Install the AOT library on non-Debug builds only.
install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
CONFIGURATIONS Profile;Release
COMPONENT Runtime)
# This file controls Flutter-level build steps. It should not be edited.
cmake_minimum_required(VERSION 3.14)
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
# Configuration provided via flutter tool.
include(${EPHEMERAL_DIR}/generated_config.cmake)
# TODO: Move the rest of this into files in ephemeral. See
# https://github.com/flutter/flutter/issues/57146.
set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
# === Flutter Library ===
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
# Published to parent scope for install step.
set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE)
list(APPEND FLUTTER_LIBRARY_HEADERS
"flutter_export.h"
"flutter_windows.h"
"flutter_messenger.h"
"flutter_plugin_registrar.h"
"flutter_texture_registrar.h"
)
list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/")
add_library(flutter INTERFACE)
target_include_directories(flutter INTERFACE
"${EPHEMERAL_DIR}"
)
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib")
add_dependencies(flutter flutter_assemble)
# === Wrapper ===
list(APPEND CPP_WRAPPER_SOURCES_CORE
"core_implementations.cc"
"standard_codec.cc"
)
list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/")
list(APPEND CPP_WRAPPER_SOURCES_PLUGIN
"plugin_registrar.cc"
)
list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/")
list(APPEND CPP_WRAPPER_SOURCES_APP
"flutter_engine.cc"
"flutter_view_controller.cc"
)
list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/")
# Wrapper sources needed for a plugin.
add_library(flutter_wrapper_plugin STATIC
${CPP_WRAPPER_SOURCES_CORE}
${CPP_WRAPPER_SOURCES_PLUGIN}
)
apply_standard_settings(flutter_wrapper_plugin)
set_target_properties(flutter_wrapper_plugin PROPERTIES
POSITION_INDEPENDENT_CODE ON)
set_target_properties(flutter_wrapper_plugin PROPERTIES
CXX_VISIBILITY_PRESET hidden)
target_link_libraries(flutter_wrapper_plugin PUBLIC flutter)
target_include_directories(flutter_wrapper_plugin PUBLIC
"${WRAPPER_ROOT}/include"
)
add_dependencies(flutter_wrapper_plugin flutter_assemble)
# Wrapper sources needed for the runner.
add_library(flutter_wrapper_app STATIC
${CPP_WRAPPER_SOURCES_CORE}
${CPP_WRAPPER_SOURCES_APP}
)
apply_standard_settings(flutter_wrapper_app)
target_link_libraries(flutter_wrapper_app PUBLIC flutter)
target_include_directories(flutter_wrapper_app PUBLIC
"${WRAPPER_ROOT}/include"
)
add_dependencies(flutter_wrapper_app flutter_assemble)
# === Flutter tool backend ===
# _phony_ is a non-existent file to force this command to run every time,
# since currently there's no way to get a full input/output list from the
# flutter tool.
set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_")
set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE)
add_custom_command(
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN}
${CPP_WRAPPER_SOURCES_APP}
${PHONY_OUTPUT}
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
windows-x64 $<CONFIG>
VERBATIM
)
add_custom_target(flutter_assemble DEPENDS
"${FLUTTER_LIBRARY}"
${FLUTTER_LIBRARY_HEADERS}
${CPP_WRAPPER_SOURCES_CORE}
${CPP_WRAPPER_SOURCES_PLUGIN}
${CPP_WRAPPER_SOURCES_APP}
)
//
// Generated file. Do not edit.
//
// clang-format off
#include "generated_plugin_registrant.h"
#include <file_selector_windows/file_selector_windows.h>
#include <firebase_core/firebase_core_plugin_c_api.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
FileSelectorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FileSelectorWindows"));
FirebaseCorePluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
}
//
// Generated file. Do not edit.
//
// clang-format off
#ifndef GENERATED_PLUGIN_REGISTRANT_
#define GENERATED_PLUGIN_REGISTRANT_
#include <flutter/plugin_registry.h>
// Registers Flutter plugins.
void RegisterPlugins(flutter::PluginRegistry* registry);
#endif // GENERATED_PLUGIN_REGISTRANT_
#
# Generated file, do not edit.
#
list(APPEND FLUTTER_PLUGIN_LIST
file_selector_windows
firebase_core
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
)
set(PLUGIN_BUNDLED_LIBRARIES)
foreach(plugin ${FLUTTER_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
endforeach(plugin)
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
endforeach(ffi_plugin)
cmake_minimum_required(VERSION 3.14)
project(runner LANGUAGES CXX)
# Define the application target. To change its name, change BINARY_NAME in the
# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer
# work.
#
# Any new source files that you add to the application should be added here.
add_executable(${BINARY_NAME} WIN32
"flutter_window.cpp"
"main.cpp"
"utils.cpp"
"win32_window.cpp"
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
"Runner.rc"
"runner.exe.manifest"
)
# Apply the standard set of build settings. This can be removed for applications
# that need different build settings.
apply_standard_settings(${BINARY_NAME})
# Add preprocessor definitions for the build version.
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"")
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}")
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}")
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}")
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}")
# Disable Windows macros that collide with C++ standard library functions.
target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
# Add dependency libraries and include directories. Add any application-specific
# dependencies here.
target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
# Run the Flutter tool portions of the build. This must not be removed.
add_dependencies(${BINARY_NAME} flutter_assemble)
// Microsoft Visual C++ generated resource script.
//
#pragma code_page(65001)
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_APP_ICON ICON "resources\\app_icon.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD)
#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD
#else
#define VERSION_AS_NUMBER 1,0,0,0
#endif
#if defined(FLUTTER_VERSION)
#define VERSION_AS_STRING FLUTTER_VERSION
#else
#define VERSION_AS_STRING "1.0.0"
#endif
VS_VERSION_INFO VERSIONINFO
FILEVERSION VERSION_AS_NUMBER
PRODUCTVERSION VERSION_AS_NUMBER
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904e4"
BEGIN
VALUE "CompanyName", "com.example" "\0"
VALUE "FileDescription", "fishtank" "\0"
VALUE "FileVersion", VERSION_AS_STRING "\0"
VALUE "InternalName", "fishtank" "\0"
VALUE "LegalCopyright", "Copyright (C) 2022 com.example. All rights reserved." "\0"
VALUE "OriginalFilename", "fishtank.exe" "\0"
VALUE "ProductName", "fishtank" "\0"
VALUE "ProductVersion", VERSION_AS_STRING "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
#include "flutter_window.h"
#include <optional>
#include "flutter/generated_plugin_registrant.h"
FlutterWindow::FlutterWindow(const flutter::DartProject& project)
: project_(project) {}
FlutterWindow::~FlutterWindow() {}
bool FlutterWindow::OnCreate() {
if (!Win32Window::OnCreate()) {
return false;
}
RECT frame = GetClientArea();
// The size here must match the window dimensions to avoid unnecessary surface
// creation / destruction in the startup path.
flutter_controller_ = std::make_unique<flutter::FlutterViewController>(
frame.right - frame.left, frame.bottom - frame.top, project_);
// Ensure that basic setup of the controller was successful.
if (!flutter_controller_->engine() || !flutter_controller_->view()) {
return false;
}
RegisterPlugins(flutter_controller_->engine());
SetChildContent(flutter_controller_->view()->GetNativeWindow());
return true;
}
void FlutterWindow::OnDestroy() {
if (flutter_controller_) {
flutter_controller_ = nullptr;
}
Win32Window::OnDestroy();
}
LRESULT
FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
WPARAM const wparam,
LPARAM const lparam) noexcept {
// Give Flutter, including plugins, an opportunity to handle window messages.
if (flutter_controller_) {
std::optional<LRESULT> result =
flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam,
lparam);
if (result) {
return *result;
}
}
switch (message) {
case WM_FONTCHANGE:
flutter_controller_->engine()->ReloadSystemFonts();
break;
}
return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
}
#ifndef RUNNER_FLUTTER_WINDOW_H_
#define RUNNER_FLUTTER_WINDOW_H_
#include <flutter/dart_project.h>
#include <flutter/flutter_view_controller.h>
#include <memory>
#include "win32_window.h"
// A window that does nothing but host a Flutter view.
class FlutterWindow : public Win32Window {
public:
// Creates a new FlutterWindow hosting a Flutter view running |project|.
explicit FlutterWindow(const flutter::DartProject& project);
virtual ~FlutterWindow();
protected:
// Win32Window:
bool OnCreate() override;
void OnDestroy() override;
LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam,
LPARAM const lparam) noexcept override;
private:
// The project to run.
flutter::DartProject project_;
// The Flutter instance hosted by this window.
std::unique_ptr<flutter::FlutterViewController> flutter_controller_;
};
#endif // RUNNER_FLUTTER_WINDOW_H_
#include <flutter/dart_project.h>
#include <flutter/flutter_view_controller.h>
#include <windows.h>
#include "flutter_window.h"
#include "utils.h"
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
_In_ wchar_t *command_line, _In_ int show_command) {
// Attach to console when present (e.g., 'flutter run') or create a
// new console when running with a debugger.
if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
CreateAndAttachConsole();
}
// Initialize COM, so that it is available for use in the library and/or
// plugins.
::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
flutter::DartProject project(L"data");
std::vector<std::string> command_line_arguments =
GetCommandLineArguments();
project.set_dart_entrypoint_arguments(std::move(command_line_arguments));
FlutterWindow window(project);
Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720);
if (!window.CreateAndShow(L"fishtank", origin, size)) {
return EXIT_FAILURE;
}
window.SetQuitOnClose(true);
::MSG msg;
while (::GetMessage(&msg, nullptr, 0, 0)) {
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
::CoUninitialize();
return EXIT_SUCCESS;
}
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Runner.rc
//
#define IDI_APP_ICON 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</windowsSettings>
</application>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 and Windows 11 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
</application>
</compatibility>
</assembly>
#include "utils.h"
#include <flutter_windows.h>
#include <io.h>
#include <stdio.h>
#include <windows.h>
#include <iostream>
void CreateAndAttachConsole() {
if (::AllocConsole()) {
FILE *unused;
if (freopen_s(&unused, "CONOUT$", "w", stdout)) {
_dup2(_fileno(stdout), 1);
}
if (freopen_s(&unused, "CONOUT$", "w", stderr)) {
_dup2(_fileno(stdout), 2);
}
std::ios::sync_with_stdio();
FlutterDesktopResyncOutputStreams();
}
}
std::vector<std::string> GetCommandLineArguments() {
// Convert the UTF-16 command line arguments to UTF-8 for the Engine to use.
int argc;
wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
if (argv == nullptr) {
return std::vector<std::string>();
}
std::vector<std::string> command_line_arguments;
// Skip the first argument as it's the binary name.
for (int i = 1; i < argc; i++) {
command_line_arguments.push_back(Utf8FromUtf16(argv[i]));
}
::LocalFree(argv);
return command_line_arguments;
}
std::string Utf8FromUtf16(const wchar_t* utf16_string) {
if (utf16_string == nullptr) {
return std::string();
}
int target_length = ::WideCharToMultiByte(
CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
-1, nullptr, 0, nullptr, nullptr);
std::string utf8_string;
if (target_length == 0 || target_length > utf8_string.max_size()) {
return utf8_string;
}
utf8_string.resize(target_length);
int converted_length = ::WideCharToMultiByte(
CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
-1, utf8_string.data(),
target_length, nullptr, nullptr);
if (converted_length == 0) {
return std::string();
}
return utf8_string;
}
#ifndef RUNNER_UTILS_H_
#define RUNNER_UTILS_H_
#include <string>
#include <vector>
// Creates a console for the process, and redirects stdout and stderr to
// it for both the runner and the Flutter library.
void CreateAndAttachConsole();
// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string
// encoded in UTF-8. Returns an empty std::string on failure.
std::string Utf8FromUtf16(const wchar_t* utf16_string);
// Gets the command line arguments passed in as a std::vector<std::string>,
// encoded in UTF-8. Returns an empty std::vector<std::string> on failure.
std::vector<std::string> GetCommandLineArguments();
#endif // RUNNER_UTILS_H_
#include "win32_window.h"
#include <flutter_windows.h>
#include "resource.h"
namespace {
constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
// The number of Win32Window objects that currently exist.
static int g_active_window_count = 0;
using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd);
// Scale helper to convert logical scaler values to physical using passed in
// scale factor
int Scale(int source, double scale_factor) {
return static_cast<int>(source * scale_factor);
}
// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module.
// This API is only needed for PerMonitor V1 awareness mode.
void EnableFullDpiSupportIfAvailable(HWND hwnd) {
HMODULE user32_module = LoadLibraryA("User32.dll");
if (!user32_module) {
return;
}
auto enable_non_client_dpi_scaling =
reinterpret_cast<EnableNonClientDpiScaling*>(
GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
if (enable_non_client_dpi_scaling != nullptr) {
enable_non_client_dpi_scaling(hwnd);
FreeLibrary(user32_module);
}
}
} // namespace
// Manages the Win32Window's window class registration.
class WindowClassRegistrar {
public:
~WindowClassRegistrar() = default;
// Returns the singleton registar instance.
static WindowClassRegistrar* GetInstance() {
if (!instance_) {
instance_ = new WindowClassRegistrar();
}
return instance_;
}
// Returns the name of the window class, registering the class if it hasn't
// previously been registered.
const wchar_t* GetWindowClass();
// Unregisters the window class. Should only be called if there are no
// instances of the window.
void UnregisterWindowClass();
private:
WindowClassRegistrar() = default;
static WindowClassRegistrar* instance_;
bool class_registered_ = false;
};
WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr;
const wchar_t* WindowClassRegistrar::GetWindowClass() {
if (!class_registered_) {
WNDCLASS window_class{};
window_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
window_class.lpszClassName = kWindowClassName;
window_class.style = CS_HREDRAW | CS_VREDRAW;
window_class.cbClsExtra = 0;
window_class.cbWndExtra = 0;
window_class.hInstance = GetModuleHandle(nullptr);
window_class.hIcon =
LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON));
window_class.hbrBackground = 0;
window_class.lpszMenuName = nullptr;
window_class.lpfnWndProc = Win32Window::WndProc;
RegisterClass(&window_class);
class_registered_ = true;
}
return kWindowClassName;
}
void WindowClassRegistrar::UnregisterWindowClass() {
UnregisterClass(kWindowClassName, nullptr);
class_registered_ = false;
}
Win32Window::Win32Window() {
++g_active_window_count;
}
Win32Window::~Win32Window() {
--g_active_window_count;
Destroy();
}
bool Win32Window::CreateAndShow(const std::wstring& title,
const Point& origin,
const Size& size) {
Destroy();
const wchar_t* window_class =
WindowClassRegistrar::GetInstance()->GetWindowClass();
const POINT target_point = {static_cast<LONG>(origin.x),
static_cast<LONG>(origin.y)};
HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST);
UINT dpi = FlutterDesktopGetDpiForMonitor(monitor);
double scale_factor = dpi / 96.0;
HWND window = CreateWindow(
window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE,
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
Scale(size.width, scale_factor), Scale(size.height, scale_factor),
nullptr, nullptr, GetModuleHandle(nullptr), this);
if (!window) {
return false;
}
return OnCreate();
}
// static
LRESULT CALLBACK Win32Window::WndProc(HWND const window,
UINT const message,
WPARAM const wparam,
LPARAM const lparam) noexcept {
if (message == WM_NCCREATE) {
auto window_struct = reinterpret_cast<CREATESTRUCT*>(lparam);
SetWindowLongPtr(window, GWLP_USERDATA,
reinterpret_cast<LONG_PTR>(window_struct->lpCreateParams));
auto that = static_cast<Win32Window*>(window_struct->lpCreateParams);
EnableFullDpiSupportIfAvailable(window);
that->window_handle_ = window;
} else if (Win32Window* that = GetThisFromHandle(window)) {
return that->MessageHandler(window, message, wparam, lparam);
}
return DefWindowProc(window, message, wparam, lparam);
}
LRESULT
Win32Window::MessageHandler(HWND hwnd,
UINT const message,
WPARAM const wparam,
LPARAM const lparam) noexcept {
switch (message) {
case WM_DESTROY:
window_handle_ = nullptr;
Destroy();
if (quit_on_close_) {
PostQuitMessage(0);
}
return 0;
case WM_DPICHANGED: {
auto newRectSize = reinterpret_cast<RECT*>(lparam);
LONG newWidth = newRectSize->right - newRectSize->left;
LONG newHeight = newRectSize->bottom - newRectSize->top;
SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth,
newHeight, SWP_NOZORDER | SWP_NOACTIVATE);
return 0;
}
case WM_SIZE: {
RECT rect = GetClientArea();
if (child_content_ != nullptr) {
// Size and position the child window.
MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left,
rect.bottom - rect.top, TRUE);
}
return 0;
}
case WM_ACTIVATE:
if (child_content_ != nullptr) {
SetFocus(child_content_);
}
return 0;
}
return DefWindowProc(window_handle_, message, wparam, lparam);
}
void Win32Window::Destroy() {
OnDestroy();
if (window_handle_) {
DestroyWindow(window_handle_);
window_handle_ = nullptr;
}
if (g_active_window_count == 0) {
WindowClassRegistrar::GetInstance()->UnregisterWindowClass();
}
}
Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept {
return reinterpret_cast<Win32Window*>(
GetWindowLongPtr(window, GWLP_USERDATA));
}
void Win32Window::SetChildContent(HWND content) {
child_content_ = content;
SetParent(content, window_handle_);
RECT frame = GetClientArea();
MoveWindow(content, frame.left, frame.top, frame.right - frame.left,
frame.bottom - frame.top, true);
SetFocus(child_content_);
}
RECT Win32Window::GetClientArea() {
RECT frame;
GetClientRect(window_handle_, &frame);
return frame;
}
HWND Win32Window::GetHandle() {
return window_handle_;
}
void Win32Window::SetQuitOnClose(bool quit_on_close) {
quit_on_close_ = quit_on_close;
}
bool Win32Window::OnCreate() {
// No-op; provided for subclasses.
return true;
}
void Win32Window::OnDestroy() {
// No-op; provided for subclasses.
}
#ifndef RUNNER_WIN32_WINDOW_H_
#define RUNNER_WIN32_WINDOW_H_
#include <windows.h>
#include <functional>
#include <memory>
#include <string>
// A class abstraction for a high DPI-aware Win32 Window. Intended to be
// inherited from by classes that wish to specialize with custom
// rendering and input handling
class Win32Window {
public:
struct Point {
unsigned int x;
unsigned int y;
Point(unsigned int x, unsigned int y) : x(x), y(y) {}
};
struct Size {
unsigned int width;
unsigned int height;
Size(unsigned int width, unsigned int height)
: width(width), height(height) {}
};
Win32Window();
virtual ~Win32Window();
// Creates and shows a win32 window with |title| and position and size using
// |origin| and |size|. New windows are created on the default monitor. Window
// sizes are specified to the OS in physical pixels, hence to ensure a
// consistent size to will treat the width height passed in to this function
// as logical pixels and scale to appropriate for the default monitor. Returns
// true if the window was created successfully.
bool CreateAndShow(const std::wstring& title,
const Point& origin,
const Size& size);
// Release OS resources associated with window.
void Destroy();
// Inserts |content| into the window tree.
void SetChildContent(HWND content);
// Returns the backing Window handle to enable clients to set icon and other
// window properties. Returns nullptr if the window has been destroyed.
HWND GetHandle();
// If true, closing this window will quit the application.
void SetQuitOnClose(bool quit_on_close);
// Return a RECT representing the bounds of the current client area.
RECT GetClientArea();
protected:
// Processes and route salient window messages for mouse handling,
// size change and DPI. Delegates handling of these to member overloads that
// inheriting classes can handle.
virtual LRESULT MessageHandler(HWND window,
UINT const message,
WPARAM const wparam,
LPARAM const lparam) noexcept;
// Called when CreateAndShow is called, allowing subclass window-related
// setup. Subclasses should return false if setup fails.
virtual bool OnCreate();
// Called when Destroy is called.
virtual void OnDestroy();
private:
friend class WindowClassRegistrar;
// OS callback called by message pump. Handles the WM_NCCREATE message which
// is passed when the non-client area is being created and enables automatic
// non-client DPI scaling so that the non-client area automatically
// responsponds to changes in DPI. All other messages are handled by
// MessageHandler.
static LRESULT CALLBACK WndProc(HWND const window,
UINT const message,
WPARAM const wparam,
LPARAM const lparam) noexcept;
// Retrieves a class instance pointer for |window|
static Win32Window* GetThisFromHandle(HWND const window) noexcept;
bool quit_on_close_ = false;
// window handle for top level window.
HWND window_handle_ = nullptr;
// window handle for hosted content.
HWND child_content_ = nullptr;
};
#endif // RUNNER_WIN32_WINDOW_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment