BioFlux:Smart Hydration

This commit is contained in:
fengshengxiong 2026-01-22 16:33:07 +08:00
commit fe3de11bc5
65 changed files with 4160 additions and 0 deletions

45
.gitignore vendored Normal file
View File

@ -0,0 +1,45 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
/coverage/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release

30
.metadata Normal file
View File

@ -0,0 +1,30 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: "d693b4b9dbac2acd4477aea4555ca6dcbea44ba2"
channel: "stable"
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: d693b4b9dbac2acd4477aea4555ca6dcbea44ba2
base_revision: d693b4b9dbac2acd4477aea4555ca6dcbea44ba2
- platform: ios
create_revision: d693b4b9dbac2acd4477aea4555ca6dcbea44ba2
base_revision: d693b4b9dbac2acd4477aea4555ca6dcbea44ba2
# 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'

16
README.md Normal file
View File

@ -0,0 +1,16 @@
# hydro_flux
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

79
about.txt Normal file
View File

@ -0,0 +1,79 @@
BioFlux - Smart Hydration Tracker
🌊 Transform Your Hydration Habits with Science-Based Tracking
BioFlux isn't just another water tracker - it's your personal hydration coach that adapts to your unique metabolic needs. Using advanced algorithms, BioFlux calculates your optimal daily water intake based on your weight, activity level, and lifestyle.
✨ KEY FEATURES
🎯 Personalized Goals
• Smart calculations based on your weight and workout intensity
• Dynamic daily targets that adjust to your activity
• Science-backed hydration recommendations
📊 Beautiful Analytics
• Elegant charts showing your hydration trends
• Weekly and monthly progress tracking
• Visual insights into your drinking patterns
💧 Intuitive Tracking
• One-tap logging with customizable drink sizes
• Multiple beverage types (water, coffee, tea, soda)
• Quick access fluid sphere buttons for instant logging
🔔 Smart Reminders
• Intelligent notifications when hydration drops
• Customizable reminder frequency
• Non-intrusive gentle nudges to stay hydrated
🎨 Stunning Design
• Beautiful glass-morphism UI design
• Dynamic color themes that respond to your hydration level
• Smooth animations and delightful interactions
📱 Seamless Experience
• Clean, minimalist interface
• Fast and responsive performance
• Offline functionality - no internet required
🏆 WHY CHOOSE BIOFLUX?
Unlike generic water trackers, BioFlux understands that hydration needs are personal. Whether you're an athlete, office worker, or busy parent, BioFlux adapts to your lifestyle and helps you maintain optimal hydration for peak performance and health.
Our metabolic-based approach ensures you're not just drinking water - you're drinking the right amount for YOUR body. Say goodbye to one-size-fits-all hydration goals and hello to personalized wellness.
🌟 PERFECT FOR:
• Fitness enthusiasts tracking workout hydration
• Health-conscious individuals optimizing daily wellness
• Anyone wanting to build better hydration habits
• People who forget to drink water regularly
• Those seeking data-driven health insights
💪 HEALTH BENEFITS:
• Improved energy levels and mental clarity
• Better skin health and appearance
• Enhanced physical performance
• Optimized metabolism and digestion
• Reduced headaches and fatigue
🔒 PRIVACY FIRST
Your health data stays on your device. BioFlux respects your privacy with local data storage and no unnecessary permissions.
📈 TRACK YOUR SUCCESS
Watch as consistent hydration transforms your daily energy, focus, and overall well-being. BioFlux makes it easy to see the connection between proper hydration and feeling your best.
Download BioFlux today and discover the difference personalized hydration can make in your life. Your body will thank you! 💙
---
App Store Categories: Health & Fitness, Lifestyle
Age Rating: 4+
Languages: English
Compatibility: iOS 12.0 or later
Size: ~25 MB
Keywords: water tracker, hydration, health, fitness, wellness, drink reminder, water intake, metabolic health, personalized nutrition, daily habits
Support: bioflux.support@example.com
Website: https://bioflux-app.com
Privacy Policy: https://bioflux-app.com/privacy

28
analysis_options.yaml Normal file
View File

@ -0,0 +1,28 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

BIN
images/bluxicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

34
ios/.gitignore vendored Normal file
View File

@ -0,0 +1,34 @@
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3

View File

@ -0,0 +1,26 @@
<?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>13.0</string>
</dict>
</plist>

View File

@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

43
ios/Podfile Normal file
View File

@ -0,0 +1,43 @@
# Uncomment this line to define a global platform for your project
platform :ios, '15.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end

213
ios/Podfile.lock Normal file
View File

@ -0,0 +1,213 @@
PODS:
- Firebase/CoreOnly (12.6.0):
- FirebaseCore (~> 12.6.0)
- Firebase/Crashlytics (12.6.0):
- Firebase/CoreOnly
- FirebaseCrashlytics (~> 12.6.0)
- firebase_analytics (12.1.0):
- firebase_core
- FirebaseAnalytics (= 12.6.0)
- Flutter
- firebase_core (4.3.0):
- Firebase/CoreOnly (= 12.6.0)
- Flutter
- firebase_crashlytics (5.0.6):
- Firebase/Crashlytics (= 12.6.0)
- firebase_core
- Flutter
- FirebaseAnalytics (12.6.0):
- FirebaseAnalytics/Default (= 12.6.0)
- FirebaseCore (~> 12.6.0)
- FirebaseInstallations (~> 12.6.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseAnalytics/Default (12.6.0):
- FirebaseCore (~> 12.6.0)
- FirebaseInstallations (~> 12.6.0)
- GoogleAppMeasurement/Default (= 12.6.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseCore (12.6.0):
- FirebaseCoreInternal (~> 12.6.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Logger (~> 8.1)
- FirebaseCoreExtension (12.6.0):
- FirebaseCore (~> 12.6.0)
- FirebaseCoreInternal (12.6.0):
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- FirebaseCrashlytics (12.6.0):
- FirebaseCore (~> 12.6.0)
- FirebaseInstallations (~> 12.6.0)
- FirebaseRemoteConfigInterop (~> 12.6.0)
- FirebaseSessions (~> 12.6.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/Environment (~> 8.1)
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
- FirebaseInstallations (12.6.0):
- FirebaseCore (~> 12.6.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- PromisesObjC (~> 2.4)
- FirebaseRemoteConfigInterop (12.6.0)
- FirebaseSessions (12.6.0):
- FirebaseCore (~> 12.6.0)
- FirebaseCoreExtension (~> 12.6.0)
- FirebaseInstallations (~> 12.6.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- nanopb (~> 3.30910.0)
- PromisesSwift (~> 2.1)
- Flutter (1.0.0)
- GoogleAdsOnDeviceConversion (3.2.0):
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Logger (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/Core (12.6.0):
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/Default (12.6.0):
- GoogleAdsOnDeviceConversion (~> 3.2.0)
- GoogleAppMeasurement/Core (= 12.6.0)
- GoogleAppMeasurement/IdentitySupport (= 12.6.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/IdentitySupport (12.6.0):
- GoogleAppMeasurement/Core (= 12.6.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleDataTransport (10.1.0):
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
- GoogleUtilities/AppDelegateSwizzler (8.1.0):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Privacy
- GoogleUtilities/Environment (8.1.0):
- GoogleUtilities/Privacy
- GoogleUtilities/Logger (8.1.0):
- GoogleUtilities/Environment
- GoogleUtilities/Privacy
- GoogleUtilities/MethodSwizzler (8.1.0):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- GoogleUtilities/Network (8.1.0):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Privacy
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (8.1.0)":
- GoogleUtilities/Privacy
- GoogleUtilities/Privacy (8.1.0)
- GoogleUtilities/Reachability (8.1.0):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- GoogleUtilities/UserDefaults (8.1.0):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- nanopb (3.30910.0):
- nanopb/decode (= 3.30910.0)
- nanopb/encode (= 3.30910.0)
- nanopb/decode (3.30910.0)
- nanopb/encode (3.30910.0)
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- PromisesObjC (2.4.0)
- PromisesSwift (2.4.0):
- PromisesObjC (= 2.4.0)
- share_plus (0.0.1):
- Flutter
- url_launcher_ios (0.0.1):
- Flutter
DEPENDENCIES:
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- firebase_crashlytics (from `.symlinks/plugins/firebase_crashlytics/ios`)
- Flutter (from `Flutter`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- share_plus (from `.symlinks/plugins/share_plus/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
SPEC REPOS:
trunk:
- Firebase
- FirebaseAnalytics
- FirebaseCore
- FirebaseCoreExtension
- FirebaseCoreInternal
- FirebaseCrashlytics
- FirebaseInstallations
- FirebaseRemoteConfigInterop
- FirebaseSessions
- GoogleAdsOnDeviceConversion
- GoogleAppMeasurement
- GoogleDataTransport
- GoogleUtilities
- nanopb
- PromisesObjC
- PromisesSwift
EXTERNAL SOURCES:
firebase_analytics:
:path: ".symlinks/plugins/firebase_analytics/ios"
firebase_core:
:path: ".symlinks/plugins/firebase_core/ios"
firebase_crashlytics:
:path: ".symlinks/plugins/firebase_crashlytics/ios"
Flutter:
:path: Flutter
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
share_plus:
:path: ".symlinks/plugins/share_plus/ios"
url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios"
SPEC CHECKSUMS:
Firebase: a451a7b61536298fd5cbfe3a746fd40443a50679
firebase_analytics: 4f9cca09e65f6c2944a862c6dc86f6bed9fb769c
firebase_core: ba00a168e719694f38960502ceb560285603d073
firebase_crashlytics: 13f4b77e9ce2a84b1f8ea07f293db5b6213ce1cf
FirebaseAnalytics: d0a97a0db6425e5a5d966340b87f92ca7b13a557
FirebaseCore: 0e38ad5d62d980a47a64b8e9301ffa311457be04
FirebaseCoreExtension: 032fd6f8509e591fda8cb76f6651f20d926b121f
FirebaseCoreInternal: 69bf1306a05b8ac43004f6cc1f804bb7b05b229e
FirebaseCrashlytics: 3d6248c50726ee7832aef0e53cb84c9e64d9fa7e
FirebaseInstallations: 631b38da2e11a83daa4bfb482f79d286a5dfa7ad
FirebaseRemoteConfigInterop: 3443b8cb8fffd76bb3e03b2a84bfd3db952fcda4
FirebaseSessions: 2e8f808347e665dff3e5843f275715f07045297d
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
GoogleAdsOnDeviceConversion: d68c69dd9581a0f5da02617b6f377e5be483970f
GoogleAppMeasurement: 3bf40aff49a601af5da1c3345702fcb4991d35ee
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
path_provider_foundation: bb55f6dbba17d0dccd6737fe6f7f34fbd0376880
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b
PODFILE CHECKSUM: 53a6aebc29ccee84c41f92f409fc20cd4ca011f1
COCOAPODS: 1.16.2

View File

@ -0,0 +1,767 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
025DDA39D7E93F60F4382EA8 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96F1E3BA61059604A42469AB /* Pods_Runner.framework */; };
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
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 */; };
CD845436FB7704CD3A90EAAA /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B45C454EF6F9C6A60758C25 /* Pods_RunnerTests.framework */; };
D883DAF12F1B64DF004E5C0E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = D883DAF02F1B64DF004E5C0E /* GoogleService-Info.plist */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
remoteInfo = Runner;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
16B4CEA5BEFA387FBFD14C89 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
2EFF9F269119EEAC18771BED /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
6435378FA59164E9C79CCEF3 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<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>"; };
87A40F8066F0614934B1379B /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
8B45C454EF6F9C6A60758C25 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
96F1E3BA61059604A42469AB /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
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>"; };
AC867E7638F997CAE9568419 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
D883DAF02F1B64DF004E5C0E /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
EA6840404EAB2C340D013FF0 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
4C508CF2318623BFF826B5A9 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
CD845436FB7704CD3A90EAAA /* Pods_RunnerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
025DDA39D7E93F60F4382EA8 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
331C8082294A63A400263BE5 /* RunnerTests */ = {
isa = PBXGroup;
children = (
331C807B294A618700263BE5 /* RunnerTests.swift */,
);
path = RunnerTests;
sourceTree = "<group>";
};
7FDD2DBF6F8FEC7A9421D640 /* Pods */ = {
isa = PBXGroup;
children = (
16B4CEA5BEFA387FBFD14C89 /* Pods-Runner.debug.xcconfig */,
AC867E7638F997CAE9568419 /* Pods-Runner.release.xcconfig */,
87A40F8066F0614934B1379B /* Pods-Runner.profile.xcconfig */,
2EFF9F269119EEAC18771BED /* Pods-RunnerTests.debug.xcconfig */,
EA6840404EAB2C340D013FF0 /* Pods-RunnerTests.release.xcconfig */,
6435378FA59164E9C79CCEF3 /* Pods-RunnerTests.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
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 */,
331C8082294A63A400263BE5 /* RunnerTests */,
7FDD2DBF6F8FEC7A9421D640 /* Pods */,
CA9ACF2465C155E10BE16347 /* Frameworks */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
D883DAF02F1B64DF004E5C0E /* GoogleService-Info.plist */,
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>";
};
CA9ACF2465C155E10BE16347 /* Frameworks */ = {
isa = PBXGroup;
children = (
96F1E3BA61059604A42469AB /* Pods_Runner.framework */,
8B45C454EF6F9C6A60758C25 /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
331C8080294A63A400263BE5 /* RunnerTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
586B53A258E12B9B12E82788 /* [CP] Check Pods Manifest.lock */,
331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */,
4C508CF2318623BFF826B5A9 /* Frameworks */,
);
buildRules = (
);
dependencies = (
331C8086294A63A400263BE5 /* PBXTargetDependency */,
);
name = RunnerTests;
productName = RunnerTests;
productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
C92652353E009CC3DC242E3B /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
23DD3CE435CDC926AA929605 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
331C8080294A63A400263BE5 = {
CreatedOnToolsVersion = 14.0;
TestTargetID = 97C146ED1CF9000F007C117D;
};
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
preferredProjectObjectVersion = 77;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
331C8080294A63A400263BE5 /* RunnerTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
331C807F294A63A400263BE5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
D883DAF12F1B64DF004E5C0E /* GoogleService-Info.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
23DD3CE435CDC926AA929605 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
586B53A258E12B9B12E82788 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
C92652353E009CC3DC242E3B /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
331C807D294A63A400263BE5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
331C8086294A63A400263BE5 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 97C146ED1CF9000F007C117D /* Runner */;
targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<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;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 77GF32A2WP;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.bioFluxSmart.bioFluxSmart;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = BioFlux;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 2EFF9F269119EEAC18771BED /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.hydroFlux.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Debug;
};
331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = EA6840404EAB2C340D013FF0 /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.hydroFlux.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Release;
};
331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 6435378FA59164E9C79CCEF3 /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.hydroFlux.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 77GF32A2WP;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.bioFluxSmart.bioFluxSmart;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = BioFlux;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 77GF32A2WP;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.bioFluxSmart.bioFluxSmart;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = BioFlux;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
331C8088294A63A400263BE5 /* Debug */,
331C8089294A63A400263BE5 /* Release */,
331C808A294A63A400263BE5 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?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>

View File

@ -0,0 +1,8 @@
<?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>

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1510"
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"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "331C8080294A63A400263BE5"
BuildableName = "RunnerTests.xctest"
BlueprintName = "RunnerTests"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
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>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?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>

View File

@ -0,0 +1,8 @@
<?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>

View File

@ -0,0 +1,13 @@
import Flutter
import UIKit
@main
@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)
}
}

View File

@ -0,0 +1,120 @@
{
"images": [
{
"size": "20x20",
"idiom": "universal",
"filename": "icon-20@2x.png",
"scale": "2x",
"platform": "ios"
},
{
"size": "20x20",
"idiom": "universal",
"filename": "icon-20@3x.png",
"scale": "3x",
"platform": "ios"
},
{
"size": "29x29",
"idiom": "universal",
"filename": "icon-29@2x.png",
"scale": "2x",
"platform": "ios"
},
{
"size": "29x29",
"idiom": "universal",
"filename": "icon-29@3x.png",
"scale": "3x",
"platform": "ios"
},
{
"size": "38x38",
"idiom": "universal",
"filename": "icon-38@2x.png",
"scale": "2x",
"platform": "ios"
},
{
"size": "38x38",
"idiom": "universal",
"filename": "icon-38@3x.png",
"scale": "3x",
"platform": "ios"
},
{
"size": "40x40",
"idiom": "universal",
"filename": "icon-40@2x.png",
"scale": "2x",
"platform": "ios"
},
{
"size": "40x40",
"idiom": "universal",
"filename": "icon-40@3x.png",
"scale": "3x",
"platform": "ios"
},
{
"size": "60x60",
"idiom": "universal",
"filename": "icon-60@2x.png",
"scale": "2x",
"platform": "ios"
},
{
"size": "60x60",
"idiom": "universal",
"filename": "icon-60@3x.png",
"scale": "3x",
"platform": "ios"
},
{
"size": "64x64",
"idiom": "universal",
"filename": "icon-64@2x.png",
"scale": "2x",
"platform": "ios"
},
{
"size": "64x64",
"idiom": "universal",
"filename": "icon-64@3x.png",
"scale": "3x",
"platform": "ios"
},
{
"size": "68x68",
"idiom": "universal",
"filename": "icon-68@2x.png",
"scale": "2x",
"platform": "ios"
},
{
"size": "76x76",
"idiom": "universal",
"filename": "icon-76@2x.png",
"scale": "2x",
"platform": "ios"
},
{
"size": "83.5x83.5",
"idiom": "universal",
"filename": "icon-83.5@2x.png",
"scale": "2x",
"platform": "ios"
},
{
"size": "1024x1024",
"idiom": "universal",
"filename": "icon-1024.png",
"scale": "1x",
"platform": "ios"
}
],
"info": {
"version": 1,
"author": "icon.wuruihong.com"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

View File

@ -0,0 +1,5 @@
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.

View File

@ -0,0 +1,37 @@
<?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>

View File

@ -0,0 +1,26 @@
<?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>

View File

@ -0,0 +1,30 @@
<?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>API_KEY</key>
<string>AIzaSyCZhzNo-5oukRLhs8yZ2nI9_AX6yrWELq8</string>
<key>GCM_SENDER_ID</key>
<string>560733077413</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.bioFluxSmart.bioFluxSmart</string>
<key>PROJECT_ID</key>
<string>bioflux-bb331</string>
<key>STORAGE_BUCKET</key>
<string>bioflux-bb331.firebasestorage.app</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:560733077413:ios:c1e6831284a2d5f6f1324c</string>
</dict>
</plist>

47
ios/Runner/Info.plist Normal file
View File

@ -0,0 +1,47 @@
<?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>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>BioFlux</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>BioFlux</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1 @@
#import "GeneratedPluginRegistrant.h"

View File

@ -0,0 +1,12 @@
import Flutter
import UIKit
import XCTest
class RunnerTests: XCTestCase {
func testExample() {
// If you add code to the Runner application, consider adding tests here.
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.
}
}

View File

@ -0,0 +1,33 @@
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart' show defaultTargetPlatform, TargetPlatform;
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
default:
throw UnsupportedError('Unsupported platform');
}
}
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'YOUR_ANDROID_API_KEY',
appId: 'YOUR_ANDROID_APP_ID',
messagingSenderId: 'YOUR_ANDROID_MESSAGING_SENDER_ID',
projectId: 'YOUR_PROJECT_ID',
storageBucket: 'YOUR_STORAGE_BUCKET',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyCZhzNo-5oukRLhs8yZ2nI9_AX6yrWELq8',
appId: '1:560733077413:ios:c1e6831284a2d5f6f1324c',
messagingSenderId: '560733077413',
projectId: 'bioflux-bb331',
storageBucket: 'bioflux-bb331.firebasestorage.app',
iosBundleId: 'com.bioFluxSmart.bioFluxSmart',
);
}

145
lib/main.dart Normal file
View File

@ -0,0 +1,145 @@
import 'dart:async';
import 'dart:ui';
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_analytics/observer.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:provider/provider.dart';
import 'adstools/firebase_optiongs.dart';
import 'services/hydration_service.dart';
import 'widgets/main_navigation_frame.dart';
bool isFirebaseInitialized = false;
void main() async {
runZonedGuarded<Future<void>>(() async {
WidgetsFlutterBinding.ensureInitialized();
try {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
).timeout(const Duration(seconds: 15)); // 15
print("✅ Firebase 初始化成功。");
isFirebaseInitialized = true; //
} on TimeoutException {
print("⚠️ Firebase 初始化超时 (超过15秒),应用将继续运行但相关功能将不可用。");
} catch (error, stack) {
print("!!!!!!!!!! Firebase 初始化失败 !!!!!!!!!!: $error");
FirebaseCrashlytics.instance.recordError(error, stack, fatal: false);
}
// Firebase
if (isFirebaseInitialized) {
//
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
// 使 App Open
AnalyticsService.instance.logAppOpen();
}
await Hive.initFlutter();
await Hive.openBox('hydrationData');
await Hive.openBox('userSettings');
final analyticsObserver = SafeFirebaseAnalyticsObserver();
runApp(
MultiProvider(
providers: [ChangeNotifierProvider(create: (_) => HydrationService())],
child: BioFluxApp(analyticsObserver: analyticsObserver),
),
);
}, (e, s) {});
}
class BioFluxApp extends StatelessWidget {
final NavigatorObserver analyticsObserver;
const BioFluxApp({super.key, required this.analyticsObserver});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'BioFlux',
navigatorObservers: [analyticsObserver],
debugShowCheckedModeBanner: false,
theme: ThemeData(
useMaterial3: true,
scaffoldBackgroundColor: const Color(0xFFF0F8FF),
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFF00BFFF),
background: const Color(0xFFF0F8FF),
),
textTheme: GoogleFonts.latoTextTheme(Theme.of(context).textTheme)
.copyWith(
displayLarge: GoogleFonts.montserrat(),
displayMedium: GoogleFonts.montserrat(),
titleLarge: GoogleFonts.montserrat(fontWeight: FontWeight.w600),
titleMedium: GoogleFonts.montserrat(fontWeight: FontWeight.w600),
bodyLarge: GoogleFonts.lato(),
bodyMedium: GoogleFonts.lato(),
),
),
home: const MainNavigationFrame(),
);
}
}
class AnalyticsService {
//
AnalyticsService._();
static final instance = AnalyticsService._();
final _analytics = FirebaseAnalytics.instance;
/// App Open
void logAppOpen() {
if (isFirebaseInitialized) {
_analytics.logAppOpen();
} else {
print("[AnalyticsService] Skipped logAppOpen: Firebase not initialized.");
}
}
}
/// FirebaseAnalyticsObserver Firebase
class SafeFirebaseAnalyticsObserver extends NavigatorObserver {
late final FirebaseAnalyticsObserver _observer;
SafeFirebaseAnalyticsObserver() {
if (isFirebaseInitialized) {
_observer = FirebaseAnalyticsObserver(
analytics: AnalyticsService.instance._analytics,
);
}
}
@override
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
if (isFirebaseInitialized) {
_observer.didPush(route, previousRoute);
}
}
@override
void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
if (isFirebaseInitialized) {
_observer.didPop(route, previousRoute);
}
}
@override
void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) {
if (isFirebaseInitialized) {
_observer.didReplace(newRoute: newRoute, oldRoute: oldRoute);
}
}
}

View File

@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
enum DrinkType {
Water, Coffee, Tea, Soda;
double get hydrationFactor {
switch (this) {
case DrinkType.Water: return 1.0;
case DrinkType.Coffee: return 0.85;
case DrinkType.Tea: return 0.90;
case DrinkType.Soda: return 0.80;
}
}
double get purityFactor {
switch (this) {
case DrinkType.Water: return 1.0;
case DrinkType.Coffee: return 0.7;
case DrinkType.Tea: return 0.85;
case DrinkType.Soda: return 0.6;
}
}
String get label => toString().split('.').last;
Color get color {
switch (this) {
case DrinkType.Water: return const Color(0xFF00BFFF);
case DrinkType.Coffee: return const Color(0xFF8D6E63);
case DrinkType.Tea: return const Color(0xFF9CCC65);
case DrinkType.Soda: return const Color(0xFFFF7043);
}
}
}

View File

@ -0,0 +1,88 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../widgets/glass_card.dart';
class FeedbackScreen extends StatefulWidget {
const FeedbackScreen({super.key});
@override
State<FeedbackScreen> createState() => _FeedbackScreenState();
}
class _FeedbackScreenState extends State<FeedbackScreen> {
final TextEditingController _controller = TextEditingController();
bool _isSubmitting = false;
void _submit() async {
if (_controller.text.isEmpty) return;
setState(() => _isSubmitting = true);
//
//
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Feedback sent! Thank you.", style: GoogleFonts.lato()),
backgroundColor: const Color(0xFF00BFFF),
behavior: SnackBarBehavior.floating,
duration: const Duration(milliseconds: 1500),
)
);
// 0.8
await Future.delayed(const Duration(milliseconds: 800));
if (mounted) {
Navigator.pop(context);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Send Feedback", style: GoogleFonts.montserrat(fontWeight: FontWeight.bold)),
backgroundColor: Colors.transparent,
elevation: 0,
centerTitle: true,
),
body: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
children: [
GlassCard(
child: TextField(
controller: _controller,
maxLines: 6,
decoration: InputDecoration(
hintText: "Tell us what you think...",
hintStyle: GoogleFonts.lato(color: Colors.grey),
border: InputBorder.none,
),
style: GoogleFonts.lato(),
),
),
const SizedBox(height: 24),
SizedBox(
width: double.infinity,
height: 50,
child: ElevatedButton(
onPressed: _isSubmitting ? null : _submit,
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF00BFFF),
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
elevation: 0,
),
child: _isSubmitting
? const SizedBox(width: 20, height: 20, child: CircularProgressIndicator(color: Colors.white, strokeWidth: 2))
: Text("Submit Feedback", style: GoogleFonts.montserrat(fontWeight: FontWeight.bold)),
),
),
],
),
),
);
}
}

View File

@ -0,0 +1,292 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import '../models/drink_type.dart';
import '../services/hydration_service.dart';
import '../widgets/fluid_sphere_button.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
final hydration = context.watch<HydrationService>();
final dynamicColor = hydration.dynamicWaterColor;
final size = MediaQuery.of(context).size;
return Scaffold(
body: Stack(
children: [
Positioned(
top: -100,
left: -100,
child: ImageFiltered(
imageFilter: ImageFilter.blur(sigmaX: 100, sigmaY: 100),
child: Container(
width: 450,
height: 450,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: dynamicColor.withOpacity(0.15),
),
),
),
),
Positioned(
top: size.height * 0.3,
right: -100,
child: ImageFiltered(
imageFilter: ImageFilter.blur(sigmaX: 80, sigmaY: 80),
child: Container(
width: 300,
height: 300,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.purpleAccent.withOpacity(0.05),
),
),
),
),
SafeArea(
child: Column(
children: [
const SizedBox(height: 10),
_buildModernHeader(context, hydration),
Expanded(
child: Center(
child: Stack(
alignment: Alignment.center,
children: [
Container(
width: 300,
height: 300,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: dynamicColor.withOpacity(0.05),
width: 1,
)
),
),
FluidSphereButton(
percentage: hydration.percentage,
waterColor: dynamicColor,
onLongPressStart: () => HapticFeedback.heavyImpact(),
onLongPressEnd: () {
context.read<HydrationService>().addWater(200);
HapticFeedback.mediumImpact();
},
),
],
),
),
),
Padding(
padding: const EdgeInsets.only(bottom: 25),
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 500),
child: Text(
hydration.statusText,
key: ValueKey(hydration.statusText),
style: GoogleFonts.montserrat(
color: dynamicColor.withOpacity(0.8),
fontSize: 13,
letterSpacing: 3.0,
fontWeight: FontWeight.w600
),
),
),
),
_buildFloatingDock(context, hydration),
const SizedBox(height: 110),
],
),
),
],
),
);
}
Widget _buildModernHeader(BuildContext context, HydrationService service) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 32.0, vertical: 20),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
DateFormat('MMM d, EEEE').format(DateTime.now()).toUpperCase(),
style: GoogleFonts.montserrat(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Colors.grey.shade400,
letterSpacing: 1.5,
),
),
const SizedBox(height: 8),
RichText(
text: TextSpan(
children: [
TextSpan(
text: "${(service.percentage * 100).toInt()}",
style: GoogleFonts.montserrat(
color: Colors.black87,
fontSize: 64,
fontWeight: FontWeight.w200,
height: 1.0,
),
),
TextSpan(
text: "%",
style: GoogleFonts.montserrat(
color: Colors.black54,
fontSize: 24,
fontWeight: FontWeight.w300,
fontFeatures: [const FontFeature.superscripts()],
),
),
],
),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.5),
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.03),
blurRadius: 10,
offset: const Offset(0, 4)
)
]
),
child: IconButton(
icon: Icon(Icons.refresh, size: 20, color: service.dynamicWaterColor),
onPressed: () {},
),
),
const SizedBox(height: 12),
Text(
"TARGET",
style: GoogleFonts.montserrat(fontSize: 10, color: Colors.grey.shade400, letterSpacing: 1),
),
Text(
"${service.dailyGoal.toInt()} ml",
style: GoogleFonts.lato(fontSize: 14, color: Colors.black87, fontWeight: FontWeight.bold),
),
],
),
],
),
],
),
);
}
Widget _buildFloatingDock(BuildContext context, HydrationService service) {
return Container(
height: 85,
margin: const EdgeInsets.symmetric(horizontal: 24),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.4),
borderRadius: BorderRadius.circular(24),
border: Border.all(color: Colors.white.withOpacity(0.4)),
boxShadow: [
BoxShadow(
color: service.dynamicWaterColor.withOpacity(0.08),
blurRadius: 20,
offset: const Offset(0, 10),
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(24),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: DrinkType.values.map((type) {
final isWater = type == DrinkType.Water;
return GestureDetector(
onTap: () {
context.read<HydrationService>().addWater(250, type: type);
HapticFeedback.lightImpact();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Recorded ${type.label}"),
backgroundColor: context.read<HydrationService>().dynamicWaterColor,
duration: const Duration(milliseconds: 800),
behavior: SnackBarBehavior.floating,
width: 200,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
)
);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: isWater ? Colors.white.withOpacity(0.8) : Colors.transparent,
shape: BoxShape.circle,
boxShadow: isWater ? [
BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 4))
] : null,
),
child: Icon(
_getIconForType(type),
color: isWater ? const Color(0xFF00BFFF) : Colors.grey.shade500,
size: 22,
),
),
const SizedBox(height: 4),
Text(
type.label,
style: GoogleFonts.montserrat(
fontSize: 10,
fontWeight: isWater ? FontWeight.w600 : FontWeight.w400,
color: isWater ? Colors.black87 : Colors.grey.shade600
),
),
],
),
);
}).toList(),
),
),
),
);
}
IconData _getIconForType(DrinkType type) {
switch(type) {
case DrinkType.Water: return Icons.water_drop;
case DrinkType.Coffee: return Icons.coffee;
case DrinkType.Tea: return Icons.emoji_food_beverage;
case DrinkType.Soda: return Icons.local_drink;
}
}
}

View File

@ -0,0 +1,107 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../widgets/glass_card.dart';
class MessageScreen extends StatelessWidget {
const MessageScreen({super.key});
@override
Widget build(BuildContext context) {
final List<Map<String, dynamic>> messages = [
{
"title": "Hydration Alert",
"body": "You haven't logged any water for 2 hours. Your metabolic sphere is starting to wither.",
"time": "10:30 AM",
"icon": Icons.warning_amber_rounded,
"color": Colors.orangeAccent,
},
{
"title": "Daily Goal Achieved!",
"body": "Congratulations! You hit your 2500ml target yesterday. Keep the streak alive!",
"time": "09:00 AM",
"icon": Icons.emoji_events_rounded,
"color": Colors.amber,
},
{
"title": "Morning Insight",
"body": "Drinking water immediately after waking up activates your internal organs.",
"time": "07:15 AM",
"icon": Icons.lightbulb_outline_rounded,
"color": Colors.blueAccent,
},
{
"title": "System Update",
"body": "Smart Metabolism Tracking is now active. We'll adjust your goals based on your workout data.",
"time": "Yesterday",
"icon": Icons.system_update_rounded,
"color": Colors.purpleAccent,
},
];
return Scaffold(
body: SafeArea(
child: ListView(
padding: const EdgeInsets.all(24),
children: [
Text(
"Notifications",
style: GoogleFonts.montserrat(fontSize: 28, fontWeight: FontWeight.bold)
),
const SizedBox(height: 20),
...messages.map((msg) => Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: _buildMessageCard(msg),
)),
],
),
),
);
}
Widget _buildMessageCard(Map<String, dynamic> msg) {
return GlassCard(
padding: const EdgeInsets.all(16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: (msg['color'] as Color).withOpacity(0.1),
shape: BoxShape.circle,
),
child: Icon(msg['icon'] as IconData, color: msg['color'] as Color, size: 24),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
msg['title'] as String,
style: GoogleFonts.montserrat(fontWeight: FontWeight.bold, fontSize: 14),
),
Text(
msg['time'] as String,
style: GoogleFonts.lato(fontSize: 10, color: Colors.grey),
),
],
),
const SizedBox(height: 6),
Text(
msg['body'] as String,
style: GoogleFonts.lato(fontSize: 13, color: Colors.grey.shade700, height: 1.4),
),
],
),
),
],
),
);
}
}

View File

@ -0,0 +1,385 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';
import 'package:share_plus/share_plus.dart';
import 'package:url_launcher/url_launcher.dart';
import '../services/hydration_service.dart';
import '../widgets/glass_card.dart';
import 'feedback_screen.dart';
class SettingsScreen extends StatelessWidget {
const SettingsScreen({super.key});
// URL
static const String privacyPolicyUrl = 'https://biofluxsmart.bitbucket.io/privacy.html';
@override
Widget build(BuildContext context) {
final service = context.watch<HydrationService>();
final color = service.dynamicWaterColor;
return Scaffold(
body: SafeArea(
child: ListView(
padding: const EdgeInsets.all(20),
children: [
Text(
"Settings",
style: GoogleFonts.montserrat(
fontSize: 28,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 20),
// Personalization
_buildSectionHeader("Personalization"),
GlassCard(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.calculate, color: color),
const SizedBox(width: 10),
Text(
"Metabolic Goals",
style: GoogleFonts.montserrat(
fontWeight: FontWeight.bold,
),
),
],
),
const Divider(height: 20),
_buildSliderRow(
label: "Weight",
value: "${service.weight.toInt()} kg",
slider: Slider(
value: service.weight,
min: 30,
max: 150,
activeColor: color,
onChanged: (v) => service.updateSettings(weight: v),
),
),
_buildSliderRow(
label: "Workout",
value: "${service.workoutMinutes.toInt()} min",
slider: Slider(
value: service.workoutMinutes,
min: 0,
max: 180,
activeColor: color,
onChanged: (v) => service.updateSettings(workout: v),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Center(
child: Text(
"Target: ${service.dailyGoal.toInt()} ml",
style: GoogleFonts.montserrat(
fontSize: 16,
color: color,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
const SizedBox(height: 20),
// Preferences
_buildSectionHeader("Preferences"),
GlassCard(
padding: EdgeInsets.zero,
child: Column(
children: [
SwitchListTile(
title: Text("Smart Reminders", style: GoogleFonts.lato()),
subtitle: Text(
"Notify when hydration drops",
style: GoogleFonts.lato(fontSize: 12, color: Colors.grey),
),
value: service.remindersEnabled,
activeColor: color,
onChanged: (v) => service.updateSettings(reminders: v),
),
const Divider(height: 1, indent: 16, endIndent: 16),
],
),
),
const SizedBox(height: 20),
// Support
_buildSectionHeader("Support"),
GlassCard(
padding: EdgeInsets.zero,
child: Column(
children: [
ListTile(
leading: Icon(
Icons.share_outlined,
color: Colors.grey.shade600,
size: 20,
),
title: Text("Share App", style: GoogleFonts.lato()),
trailing: const Icon(
Icons.chevron_right,
size: 18,
color: Colors.black26,
),
onTap: () {
Share.share(
'Check out BioFlux - The Metabolic Hydration Tracker! Stay fluid.',
);
},
),
const Divider(height: 1, indent: 16, endIndent: 16),
ListTile(
leading: Icon(
Icons.chat_bubble_outline,
color: Colors.grey.shade600,
size: 20,
),
title: Text("Send Feedback", style: GoogleFonts.lato()),
trailing: const Icon(
Icons.chevron_right,
size: 18,
color: Colors.black26,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const FeedbackScreen(),
),
);
},
),
const Divider(height: 1, indent: 16, endIndent: 16),
ListTile(
leading: Icon(
Icons.lock_outline,
color: Colors.grey.shade600,
size: 20,
),
title: Text("Privacy Policy", style: GoogleFonts.lato()),
trailing: const Icon(
Icons.chevron_right,
size: 18,
color: Colors.black26,
),
onTap: () => _launchPrivacyPolicy(context),
),
const Divider(height: 1, indent: 16, endIndent: 16),
ListTile(
leading: Icon(
Icons.info_outline,
color: Colors.grey.shade600,
size: 20,
),
title: Text("About BioFlux", style: GoogleFonts.lato()),
trailing: const Icon(
Icons.chevron_right,
size: 18,
color: Colors.black26,
),
onTap: () => _showAboutDialog(context),
),
],
),
),
const SizedBox(height: 100),
],
),
),
);
}
Widget _buildSectionHeader(String title) {
return Padding(
padding: const EdgeInsets.only(left: 8, bottom: 8),
child: Text(
title.toUpperCase(),
style: GoogleFonts.montserrat(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.grey.shade500,
letterSpacing: 1.2,
),
),
);
}
Widget _buildSliderRow({
required String label,
required String value,
required Widget slider,
}) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(label, style: GoogleFonts.lato()),
Text(value, style: GoogleFonts.lato(fontWeight: FontWeight.bold)),
],
),
SizedBox(height: 30, child: slider),
],
);
}
//
Future<void> _launchPrivacyPolicy(BuildContext context) async {
try {
final Uri url = Uri.parse(privacyPolicyUrl);
if (await canLaunchUrl(url)) {
await launchUrl(url, mode: LaunchMode.externalApplication);
} else {
if (context.mounted) {
_showErrorDialog(context, 'Unable to open privacy policy');
}
}
} catch (e) {
if (context.mounted) {
_showErrorDialog(context, 'Error opening privacy policy: $e');
}
}
}
//
void _showAboutDialog(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
title: Row(
children: [
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue.shade400, Colors.cyan.shade300],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(
Icons.water_drop,
color: Colors.white,
size: 24,
),
),
const SizedBox(width: 12),
Text(
"BioFlux",
style: GoogleFonts.montserrat(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
],
),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Smart Hydration Tracker",
style: GoogleFonts.lato(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Colors.grey.shade700,
),
),
const SizedBox(height: 16),
Text(
"Version 1.0.0",
style: GoogleFonts.lato(
fontSize: 14,
color: Colors.grey.shade600,
),
),
const SizedBox(height: 16),
Text(
"BioFlux helps you maintain optimal hydration levels based on your metabolic needs. Track your daily water intake, set personalized goals, and receive smart reminders to stay healthy and hydrated.",
style: GoogleFonts.lato(fontSize: 14, height: 1.5),
),
const SizedBox(height: 16),
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.blue.shade50,
borderRadius: BorderRadius.circular(8),
),
child: Row(
children: [
Icon(Icons.favorite, color: Colors.red.shade400, size: 16),
const SizedBox(width: 8),
Expanded(
child: Text(
"Made with care for your health",
style: GoogleFonts.lato(
fontSize: 12,
color: Colors.grey.shade700,
),
),
),
],
),
),
],
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(
"Close",
style: GoogleFonts.lato(fontWeight: FontWeight.w600),
),
),
],
);
},
);
}
//
void _showErrorDialog(BuildContext context, String message) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(
"Error",
style: GoogleFonts.montserrat(fontWeight: FontWeight.bold),
),
content: Text(message, style: GoogleFonts.lato()),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(
"OK",
style: GoogleFonts.lato(fontWeight: FontWeight.w600),
),
),
],
);
},
);
}
}

View File

@ -0,0 +1,154 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';
import '../services/hydration_service.dart';
import '../widgets/glass_card.dart';
class StatsScreen extends StatelessWidget {
const StatsScreen({super.key});
@override
Widget build(BuildContext context) {
final service = context.watch<HydrationService>();
final history = service.history;
final color = service.dynamicWaterColor;
return Scaffold(
body: SafeArea(
child: ListView(
padding: const EdgeInsets.all(24.0),
children: [
Text(
"Insights",
style: GoogleFonts.montserrat(fontSize: 28, fontWeight: FontWeight.bold)
),
const SizedBox(height: 20),
Row(
children: [
_buildMetricCard("Streak", "5 Days", Icons.local_fire_department, Colors.orange),
const SizedBox(width: 12),
_buildMetricCard("Avg", "1.8 L", Icons.water, Colors.blue),
const SizedBox(width: 12),
_buildMetricCard("Goal", "90%", Icons.check_circle, Colors.green),
],
),
const SizedBox(height: 24),
Text("Intake Breakdown", style: GoogleFonts.montserrat(fontSize: 16, fontWeight: FontWeight.w600)),
const SizedBox(height: 12),
GlassCard(
child: Column(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(10),
child: SizedBox(
height: 12,
child: Row(
children: service.breakdown.entries.map((entry) {
if (entry.value == 0) return const SizedBox.shrink();
final flex = (entry.value * 10).toInt();
return Expanded(
flex: flex == 0 ? 1 : flex,
child: Container(color: entry.key.color),
);
}).toList(),
),
),
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: service.breakdown.entries.where((e) => e.value > 0).map((entry) {
return Row(
children: [
Container(width: 8, height: 8, decoration: BoxDecoration(color: entry.key.color, shape: BoxShape.circle)),
const SizedBox(width: 6),
Text(entry.key.label, style: GoogleFonts.lato(fontSize: 12, color: Colors.grey.shade700)),
],
);
}).toList(),
)
],
),
),
const SizedBox(height: 24),
Text("Weekly Overview", style: GoogleFonts.montserrat(fontSize: 16, fontWeight: FontWeight.w600)),
const SizedBox(height: 12),
AspectRatio(
aspectRatio: 1.5,
child: GlassCard(
child: Padding(
padding: const EdgeInsets.only(right: 16, top: 16, bottom: 0),
child: BarChart(
BarChartData(
gridData: const FlGridData(show: false),
titlesData: FlTitlesData(
show: true,
rightTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
topTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
leftTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
getTitlesWidget: (value, meta) {
const days = ['M', 'T', 'W', 'T', 'F', 'S', 'S'];
if (value.toInt() < days.length) {
return Text(days[value.toInt()], style: GoogleFonts.lato(fontSize: 10, color: Colors.grey));
}
return const SizedBox();
},
),
),
),
borderData: FlBorderData(show: false),
barGroups: history.asMap().entries.map((e) {
return BarChartGroupData(
x: e.key,
barRods: [
BarChartRodData(
toY: e.value,
color: e.value >= service.dailyGoal ? color : color.withOpacity(0.5),
width: 12,
borderRadius: BorderRadius.circular(6),
backDrawRodData: BackgroundBarChartRodData(
show: true,
toY: 4000,
color: Colors.grey.withOpacity(0.1),
),
),
],
);
}).toList(),
),
),
),
),
),
const SizedBox(height: 80),
],
),
),
);
}
Widget _buildMetricCard(String title, String value, IconData icon, Color color) {
return Expanded(
child: GlassCard(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(icon, size: 20, color: color),
const SizedBox(height: 8),
Text(value, style: GoogleFonts.montserrat(fontSize: 18, fontWeight: FontWeight.bold)),
Text(title, style: GoogleFonts.lato(fontSize: 12, color: Colors.grey.shade600)),
],
),
),
);
}
}

View File

@ -0,0 +1,145 @@
import 'dart:async';
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:intl/intl.dart';
import '../models/drink_type.dart';
class HydrationService extends ChangeNotifier {
final Box _dataBox = Hive.box('hydrationData');
final Box _settingsBox = Hive.box('userSettings');
double _currentIntake = 0.0;
double _purityScore = 1.0;
DateTime _lastDrinkTime = DateTime.now();
Map<DrinkType, double> _breakdown = {
DrinkType.Water: 0,
DrinkType.Coffee: 0,
DrinkType.Tea: 0,
DrinkType.Soda: 0,
};
double _weight = 60.0;
double _workoutMinutes = 0.0;
bool _remindersEnabled = true;
double _reminderInterval = 60.0;
List<double> _history = [];
Timer? _decayTimer;
HydrationService() {
_loadData();
_startDecayCheck();
}
double get currentIntake => _currentIntake;
double get dailyGoal => (_weight * 35.0) + (_workoutMinutes * 8.0);
double get percentage => (_currentIntake / dailyGoal).clamp(0.0, 1.0);
List<double> get history => _history;
double get weight => _weight;
double get workoutMinutes => _workoutMinutes;
bool get remindersEnabled => _remindersEnabled;
double get reminderInterval => _reminderInterval;
Map<DrinkType, double> get breakdown => _breakdown;
Color get dynamicWaterColor {
Color baseColor = const Color(0xFF00BFFF);
Color impurityColor = const Color(0xFFD2B48C);
Color blendedWithImpurity = Color.lerp(impurityColor, baseColor, _purityScore)!;
final minutesSince = DateTime.now().difference(_lastDrinkTime).inMinutes;
double freshness = 1.0;
if (minutesSince > 120) {
double overdueHours = (minutesSince - 120) / 60.0;
freshness = (1.0 - (overdueHours * 0.2)).clamp(0.4, 1.0);
}
Color dryColor = Colors.grey.shade400;
return Color.lerp(dryColor, blendedWithImpurity, freshness)!;
}
String get statusText {
final minutesSince = DateTime.now().difference(_lastDrinkTime).inMinutes;
if (minutesSince > 120) return "Body is withering...";
if (_purityScore < 0.7) return "Purify your system";
return "Metabolism Optimal";
}
void _loadData() {
final todayKey = DateFormat('yyyyMMdd').format(DateTime.now());
_currentIntake = _dataBox.get(todayKey, defaultValue: 0.0);
_purityScore = _dataBox.get('purity_$todayKey', defaultValue: 1.0);
int? lastTs = _dataBox.get('last_drink_ts');
_lastDrinkTime = lastTs != null ? DateTime.fromMillisecondsSinceEpoch(lastTs) : DateTime.now();
_weight = _settingsBox.get('weight', defaultValue: 60.0);
_workoutMinutes = _settingsBox.get('workout', defaultValue: 0.0);
_remindersEnabled = _settingsBox.get('reminders', defaultValue: true);
_reminderInterval = _settingsBox.get('reminderInterval', defaultValue: 60.0);
if (_history.isEmpty) {
for (int i = 0; i < 7; i++) {
_history.add(1500 + math.Random().nextInt(1500).toDouble());
}
}
_breakdown = {
DrinkType.Water: _currentIntake * 0.7,
DrinkType.Coffee: _currentIntake * 0.2,
DrinkType.Tea: _currentIntake * 0.1,
DrinkType.Soda: 0,
};
notifyListeners();
}
void updateSettings({double? weight, double? workout, bool? reminders, double? interval}) {
if (weight != null) _weight = weight;
if (workout != null) _workoutMinutes = workout;
if (reminders != null) _remindersEnabled = reminders;
if (interval != null) _reminderInterval = interval;
_settingsBox.put('weight', _weight);
_settingsBox.put('workout', _workoutMinutes);
_settingsBox.put('reminders', _remindersEnabled);
_settingsBox.put('reminderInterval', _reminderInterval);
notifyListeners();
}
void addWater(double amount, {DrinkType type = DrinkType.Water}) {
double efficientAmount = amount * type.hydrationFactor;
_currentIntake += efficientAmount;
_breakdown[type] = (_breakdown[type] ?? 0) + efficientAmount;
if (type == DrinkType.Water) {
_purityScore = (_purityScore + 0.15).clamp(0.0, 1.0);
} else {
_purityScore = (_purityScore - (1.0 - type.purityFactor)).clamp(0.0, 1.0);
}
_lastDrinkTime = DateTime.now();
final todayKey = DateFormat('yyyyMMdd').format(DateTime.now());
_dataBox.put(todayKey, _currentIntake);
_dataBox.put('purity_$todayKey', _purityScore);
_dataBox.put('last_drink_ts', _lastDrinkTime.millisecondsSinceEpoch);
notifyListeners();
}
void _startDecayCheck() {
_decayTimer = Timer.periodic(const Duration(minutes: 1), (timer) {
notifyListeners();
});
}
@override
void dispose() {
_decayTimer?.cancel();
super.dispose();
}
}

View File

@ -0,0 +1,137 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'wave_painter.dart';
class FluidSphereButton extends StatefulWidget {
final double percentage;
final Color waterColor;
final VoidCallback onLongPressStart;
final VoidCallback onLongPressEnd;
const FluidSphereButton({
super.key,
required this.percentage,
required this.waterColor,
required this.onLongPressStart,
required this.onLongPressEnd,
});
@override
State<FluidSphereButton> createState() => _FluidSphereButtonState();
}
class _FluidSphereButtonState extends State<FluidSphereButton>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 4),
)..repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onLongPress: widget.onLongPressStart,
onLongPressUp: widget.onLongPressEnd,
child: AnimatedContainer(
duration: const Duration(seconds: 1),
width: 260,
height: 260,
decoration: BoxDecoration(
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: widget.waterColor.withOpacity(0.3),
blurRadius: 40,
offset: const Offset(0, 20),
),
BoxShadow(
color: Colors.white.withOpacity(0.9),
blurRadius: 20,
offset: const Offset(-10, -10),
),
],
),
child: ClipOval(
child: Stack(
children: [
Container(color: Colors.white.withOpacity(0.2)),
AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return CustomPaint(
painter: WavePainter(
animationValue: _controller.value,
percentage: widget.percentage,
color: widget.waterColor,
),
size: Size.infinite,
);
},
),
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.white.withOpacity(0.6),
Colors.transparent,
Colors.transparent,
Colors.white.withOpacity(0.1),
],
stops: const [0.0, 0.4, 0.7, 1.0],
),
),
),
Positioned(
top: 30,
right: 30,
child: Container(
width: 40,
height: 20,
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.4),
borderRadius: const BorderRadius.all(Radius.elliptical(40, 20)),
),
),
),
Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"HOLD TO INFUSE",
style: GoogleFonts.montserrat(
color: widget.percentage > 0.6 ? Colors.white : Colors.black45,
fontSize: 10,
letterSpacing: 2.0,
fontWeight: FontWeight.w700,
),
),
],
),
),
],
),
),
),
);
}
}

View File

@ -0,0 +1,49 @@
import 'dart:ui';
import 'package:flutter/material.dart';
class GlassCard extends StatelessWidget {
final Widget child;
final double? width;
final double? height;
final EdgeInsetsGeometry padding;
const GlassCard({
super.key,
required this.child,
this.width,
this.height,
this.padding = const EdgeInsets.all(16),
});
@override
Widget build(BuildContext context) {
return ClipRRect(
borderRadius: BorderRadius.circular(20),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: Container(
width: width,
height: height,
padding: padding,
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.65),
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: Colors.white.withOpacity(0.6),
width: 1.0,
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.03),
blurRadius: 15,
offset: const Offset(0, 5),
),
],
),
child: child,
),
),
);
}
}

View File

@ -0,0 +1,78 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';
import '../screens/home_screen.dart';
import '../screens/message_screen.dart';
import '../screens/settings_screen.dart';
import '../screens/stats_screen.dart';
import '../services/hydration_service.dart';
class MainNavigationFrame extends StatefulWidget {
const MainNavigationFrame({super.key});
@override
State<MainNavigationFrame> createState() => _MainNavigationFrameState();
}
class _MainNavigationFrameState extends State<MainNavigationFrame> {
int _currentIndex = 0;
final List<Widget> _pages = [
const HomeScreen(),
const MessageScreen(),
const StatsScreen(),
const SettingsScreen(),
];
@override
Widget build(BuildContext context) {
final service = context.watch<HydrationService>();
final activeColor = service.dynamicWaterColor;
return Scaffold(
extendBody: true,
body: _pages[_currentIndex],
bottomNavigationBar: Container(
margin: const EdgeInsets.only(left: 20, right: 20, bottom: 30),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.8),
borderRadius: BorderRadius.circular(30),
boxShadow: [
BoxShadow(
color: activeColor.withOpacity(0.15),
blurRadius: 25,
offset: const Offset(0, 8),
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(30),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15),
child: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) => setState(() => _currentIndex = index),
backgroundColor: Colors.transparent,
elevation: 0,
type: BottomNavigationBarType.fixed,
selectedItemColor: activeColor,
unselectedItemColor: Colors.grey.shade400,
selectedLabelStyle: GoogleFonts.montserrat(fontSize: 10, fontWeight: FontWeight.w600),
unselectedLabelStyle: GoogleFonts.montserrat(fontSize: 10),
showSelectedLabels: false,
showUnselectedLabels: false,
items: const [
BottomNavigationBarItem(icon: Icon(Icons.water_drop_rounded), label: 'Home'),
BottomNavigationBarItem(icon: Icon(Icons.notifications_none_rounded), label: 'Msg'),
BottomNavigationBarItem(icon: Icon(Icons.bar_chart_rounded), label: 'Stats'),
BottomNavigationBarItem(icon: Icon(Icons.settings_outlined), label: 'Settings'),
],
),
),
),
),
);
}
}

View File

@ -0,0 +1,63 @@
import 'dart:math' as math;
import 'package:flutter/material.dart';
class WavePainter extends CustomPainter {
final double animationValue;
final double percentage;
final Color color;
WavePainter({
required this.animationValue,
required this.percentage,
required this.color,
});
@override
void paint(Canvas canvas, Size size) {
final double baseHeight = size.height * (1 - percentage);
final Paint paint1 = Paint()
..color = color.withOpacity(0.8)
..style = PaintingStyle.fill;
final Paint paint2 = Paint()
..color = color.withOpacity(0.5)
..style = PaintingStyle.fill;
final path1 = Path();
final path2 = Path();
path1.moveTo(0, baseHeight);
path2.moveTo(0, baseHeight);
for (double i = 0.0; i <= size.width; i++) {
path1.lineTo(
i,
baseHeight + math.sin((i / size.width * 2 * math.pi) + (animationValue * 2 * math.pi)) * 10,
);
path2.lineTo(
i,
baseHeight + math.sin((i / size.width * 2 * math.pi) + (animationValue * 2 * math.pi) + 1.5) * 12,
);
}
path1.lineTo(size.width, size.height);
path1.lineTo(0, size.height);
path1.close();
path2.lineTo(size.width, size.height);
path2.lineTo(0, size.height);
path2.close();
canvas.drawPath(path2, paint2);
canvas.drawPath(path1, paint1);
}
@override
bool shouldRepaint(covariant WavePainter oldDelegate) {
return oldDelegate.animationValue != animationValue ||
oldDelegate.percentage != percentage ||
oldDelegate.color != color;
}
}

602
pubspec.lock Normal file
View File

@ -0,0 +1,602 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
_flutterfire_internals:
dependency: transitive
description:
name: _flutterfire_internals
sha256: e4a1b612fd2955908e26116075b3a4baf10c353418ca645b4deae231c82bf144
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.65"
async:
dependency: transitive
description:
name: async
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.13.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.2"
characters:
dependency: transitive
description:
name: characters
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.4.0"
clock:
dependency: transitive
description:
name: clock
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.2"
collection:
dependency: transitive
description:
name: collection
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.19.1"
cross_file:
dependency: transitive
description:
name: cross_file
sha256: "701dcfc06da0882883a2657c445103380e53e647060ad8d9dfb710c100996608"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.3.5+1"
crypto:
dependency: transitive
description:
name: crypto
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.7"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.8"
equatable:
dependency: transitive
description:
name: equatable
sha256: "3e0141505477fd8ad55d6eb4e7776d3fe8430be8e497ccb1521370c3f21a3e2b"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.8"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.3"
ffi:
dependency: transitive
description:
name: ffi
sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.4"
file:
dependency: transitive
description:
name: file
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
url: "https://pub.flutter-io.cn"
source: hosted
version: "7.0.1"
firebase_analytics:
dependency: "direct main"
description:
name: firebase_analytics
sha256: "8ca4832c7a6d145ce987fd07d6dfbb8c91d9058178342f20de6305fb77b1b40d"
url: "https://pub.flutter-io.cn"
source: hosted
version: "12.1.0"
firebase_analytics_platform_interface:
dependency: transitive
description:
name: firebase_analytics_platform_interface
sha256: d00234716f415f89eb5c2cefb1238d7fd2f3120275d71414b84ae434dcdb7a19
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.0.5"
firebase_analytics_web:
dependency: transitive
description:
name: firebase_analytics_web
sha256: e42b294e51aedb4bd4b761a886c8d6b473c44b44aa4c0b47cab06b2c66ac3fba
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.6.1+1"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
sha256: "29cfa93c771d8105484acac340b5ea0835be371672c91405a300303986f4eba9"
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.3.0"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
sha256: cccb4f572325dc14904c02fcc7db6323ad62ba02536833dddb5c02cac7341c64
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.0.2"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
sha256: a631bbfbfa26963d68046aed949df80b228964020e9155b086eff94f462bbf1f
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.3.1"
firebase_crashlytics:
dependency: "direct main"
description:
name: firebase_crashlytics
sha256: "8d52022ee6fdd224e92c042f297d1fd0ec277195c49f39fa61b8cc500a639f00"
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.0.6"
firebase_crashlytics_platform_interface:
dependency: transitive
description:
name: firebase_crashlytics_platform_interface
sha256: "97c6a97b35e3d3dafe38fb053a65086a1efb125022d292161405848527cc25a4"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.8.16"
fixnum:
dependency: transitive
description:
name: fixnum
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.1"
fl_chart:
dependency: "direct main"
description:
name: fl_chart
sha256: "7ca9a40f4eb85949190e54087be8b4d6ac09dc4c54238d782a34cf1f7c011de9"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.1"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.0.0"
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"
google_fonts:
dependency: "direct main"
description:
name: google_fonts
sha256: ba03d03bcaa2f6cb7bd920e3b5027181db75ab524f8891c8bc3aa603885b8055
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.3.3"
hive:
dependency: "direct main"
description:
name: hive
sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.3"
hive_flutter:
dependency: "direct main"
description:
name: hive_flutter
sha256: dca1da446b1d808a51689fb5d0c6c9510c0a2ba01e22805d492c73b68e33eecc
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.0"
http:
dependency: transitive
description:
name: http
sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.6.0"
http_parser:
dependency: transitive
description:
name: http_parser
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.1.2"
intl:
dependency: "direct main"
description:
name: intl
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.20.2"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
url: "https://pub.flutter-io.cn"
source: hosted
version: "11.0.2"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.10"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.2"
lints:
dependency: transitive
description:
name: lints
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.1.1"
matcher:
dependency: transitive
description:
name: matcher
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.12.17"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.16.0"
mime:
dependency: transitive
description:
name: mime
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.0"
nested:
dependency: transitive
description:
name: nested
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.0"
path:
dependency: transitive
description:
name: path
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.9.1"
path_provider:
dependency: transitive
description:
name: path_provider
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.5"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: f2c65e21139ce2c3dad46922be8272bb5963516045659e71bb16e151c93b580e
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.22"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "6d13aece7b3f5c5a9731eaf553ff9dcbc2eff41087fd2df587fd0fed9a3eb0c4"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.5.1"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.2"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.3.0"
platform:
dependency: transitive
description:
name: platform
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.1.6"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.8"
provider:
dependency: "direct main"
description:
name: provider
sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272"
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.1.5+1"
share_plus:
dependency: "direct main"
description:
name: share_plus
sha256: "14c8860d4de93d3a7e53af51bff479598c4e999605290756bbbe45cf65b37840"
url: "https://pub.flutter-io.cn"
source: hosted
version: "12.0.1"
share_plus_platform_interface:
dependency: transitive
description:
name: share_plus_platform_interface
sha256: "88023e53a13429bd65d8e85e11a9b484f49d4c190abbd96c7932b74d6927cc9a"
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.1.0"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
source_span:
dependency: transitive
description:
name: source_span
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.10.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.12.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.4"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.4.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.2"
test_api:
dependency: transitive
description:
name: test_api
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.7.6"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.4.0"
url_launcher:
dependency: "direct main"
description:
name: url_launcher
sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.3.2"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: "767344bf3063897b5cf0db830e94f904528e6dd50a6dfaf839f0abf509009611"
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.3.28"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: cfde38aa257dae62ffe79c87fab20165dfdf6988c1d31b58ebf59b9106062aad
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.3.6"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.2.2"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.2.5"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.3.2"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.1"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.1.5"
uuid:
dependency: transitive
description:
name: uuid
sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.5.2"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.0"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
url: "https://pub.flutter-io.cn"
source: hosted
version: "15.0.2"
web:
dependency: transitive
description:
name: web
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.1"
win32:
dependency: transitive
description:
name: win32
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.15.0"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.0"
sdks:
dart: ">=3.9.2 <4.0.0"
flutter: ">=3.35.0"

69
pubspec.yaml Normal file
View File

@ -0,0 +1,69 @@
name: bio_flux
description: "BioFlux:Smart Hydration."
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1
environment:
sdk: ^3.9.2
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.8
share_plus: ^12.0.1
provider: ^6.1.5+1
hive: ^2.2.3
hive_flutter: ^1.1.0
fl_chart: ^1.1.1
intl: ^0.20.2
google_fonts: ^6.3.3
firebase_core: ^4.3.0
firebase_crashlytics: ^5.0.6
firebase_analytics: ^12.1.0
url_launcher: ^6.3.2
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^5.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
assets:
- images/

30
test/widget_test.dart Normal file
View File

@ -0,0 +1,30 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hydro_flux/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}