diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3a83c2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# See https://www.dartlang.org/guides/libraries/private-files + +# Files and directories created by pub +.dart_tool/ +.packages +build/ +# If you're building an application, you may want to check-in your pubspec.lock +pubspec.lock + +# Directory created by dartdoc +# If you don't generate documentation locally you can remove this line. +doc/api/ + +# dotenv environment variables file +.env* + +# Avoid committing generated Javascript files: +*.dart.js +*.info.json # Produced by the --dump-info flag. +*.js # When generated by dart2js. Don't specify *.js if your + # project includes source files written in JavaScript. +*.js_ +*.js.deps +*.js.map + +.flutter-plugins +.flutter-plugins-dependencies diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..0c50e4f --- /dev/null +++ b/.metadata @@ -0,0 +1,10 @@ +# 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: e6b34c2b5c96bb95325269a29a84e83ed8909b5f + channel: stable + +project_type: app diff --git a/README.md b/README.md new file mode 100644 index 0000000..df792fc --- /dev/null +++ b/README.md @@ -0,0 +1,50 @@ +

+

+ +## MyWaifu +
MyWaifu: A mobile app that allows you to choose, customize and watch your very own waifu!
+ +## 📲About MyWaifu +MyWaifu is an Augmented Reality app that allows users to have their own choice of "partner" in their phone. Users are able to choose between various waifu types and buy clothes for their waifu. + +After clicking one of the panels in the home page, users can view their waifu through their camera via Google Scene Viewer! + +Since this is a demo app, some of the code hasn't been changed from the flutter template we used as the base of this project to make UI and sign up process easier. Note that all the Augmentated Reality, Waifu Types and Shopping Choices were made from scratch in only 12 hours of work, including research time since we're begineers. + +## 📸 Screenshots + +||| +|:----------------------------------------:|:-----------------------------------------:| +| ![image](https://i.ibb.co/rxccJNh/home.jpg) | ![image](https://i.ibb.co/Jp0Z3pP/navigation.jpg) | +| ![image](https://i.ibb.co/PDYs0W8/3dmodel.jpg)| ![image](https://i.ibb.co/dcXKL4P/ar.jpg) | +| ![image](https://i.ibb.co/bmxpsBd/shopping.jpg)| ![image](https://i.ibb.co/4WPTNzT/type.jpg) | +| ![image](https://i.ibb.co/r3pZ1WW/about.jpg) | + +#### 🌲Features +1. An interactive and engaging app that allows you to have a virtual girlfriend, strictly only through Flutter. +2. Customize your virtual significant other's clothing and shop for them. +3. Choose or replace your virtual waifu type in an instant! +4. Supports both iOS and Android devices. + +## 🚀Team +The MyWaifu mobile app was developed by a group formed during the Flutter Bootcamp organized by Google Developer Student Clubs (GDSC) Asia Pacific University and University of Malaya. After learning basics of Flutter in the workshops, we worked together to finish the project from scratch under 12 hours through the night, to pitch it the next day! + +Yeo Yee Tao +• GitHub: https://github.com/yeetao13 +• Instagram: https://www.instagram.com/yeetaoyeo/ +• LinkedIn: https://www.linkedin.com/in/yee-tao-yeo-3ab555228/ + +Sattish Pratap Shewkani +• GitHub: https://github.com/Sattishh +• Instagram: https://www.instagram.com/sattish_s/ +• LinkedIn: https://www.linkedin.com/in/sattishh/ + +Quah Seng Kit +• GitHub: https://github.com/jaylearnscode +• Instagram: https://www.instagram.com/seng.kit/ +• LinkedIn: https://www.linkedin.com/in/quah-seng-kit-771690252/ + +Elias Yap +• GitHub: https://github.com/Eithne42 +• Instagram: https://www.instagram.com/teng.yy/ +• LinkedIn: https://www.linkedin.com/in/ellis-yap/ \ No newline at end of file diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..bc2100d --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,7 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000..8d0ff49 --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,79 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + + compileSdkVersion flutter.compileSdkVersion + ndkVersion flutter.ndkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + compileOptions { + sourceCompatibility 1.8 + targetCompatibility 1.8 + } + + kotlinOptions { + jvmTarget = '1.8' + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.best_flutter_ui_templates" + minSdkVersion 24 + targetSdkVersion flutter.targetSdkVersion + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation 'com.google.ar.sceneform.ux:sceneform-ux:1.8.0' + + // Alternatively, use ArSceneView without the UX dependency. + implementation 'com.google.ar.sceneform:core:1.8.0' + implementation 'com.google.ar:core:1.33.0' +} diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..a290b77 --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,39 @@ +{ + "project_info": { + "project_number": "977448159531", + "project_id": "ecoar-2c526", + "storage_bucket": "ecoar-2c526.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:977448159531:android:8b62a3f33493580cfb1d6e", + "android_client_info": { + "package_name": "com.example.best_flutter_ui_templates" + } + }, + "oauth_client": [ + { + "client_id": "977448159531-3svabt3plmgdpogm57m96lrhm9dkuk22.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDwToAGeuW3NI8qnfHoTlj2LRXuGHyfwq4" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "977448159531-3svabt3plmgdpogm57m96lrhm9dkuk22.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..35caba3 --- /dev/null +++ b/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..4f3d1ef --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/kotlin/com/example/best_flutter_ui_templates/MainActivity.kt b/android/app/src/main/kotlin/com/example/best_flutter_ui_templates/MainActivity.kt new file mode 100644 index 0000000..663c7b3 --- /dev/null +++ b/android/app/src/main/kotlin/com/example/best_flutter_ui_templates/MainActivity.kt @@ -0,0 +1,6 @@ +package com.example.best_flutter_ui_templates + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..ef4e8a5 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..11b5c14 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..0c85938 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..00938b7 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..862d00d Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..1f83a33 --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..35caba3 --- /dev/null +++ b/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..31e9577 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,31 @@ +buildscript { + ext.kotlin_version = '1.6.10' + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:7.1.2' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..38c8d45 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true +android.useAndroidX=true +android.enableJetifier=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..cc5527d --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..5a2f14f --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/assets/fonts/Inter-Black.ttf b/assets/fonts/Inter-Black.ttf new file mode 100644 index 0000000..5aecf7d Binary files /dev/null and b/assets/fonts/Inter-Black.ttf differ diff --git a/assets/fonts/Inter-Bold.ttf b/assets/fonts/Inter-Bold.ttf new file mode 100644 index 0000000..8e82c70 Binary files /dev/null and b/assets/fonts/Inter-Bold.ttf differ diff --git a/assets/fonts/Inter-ExtraBold.ttf b/assets/fonts/Inter-ExtraBold.ttf new file mode 100644 index 0000000..cb4b821 Binary files /dev/null and b/assets/fonts/Inter-ExtraBold.ttf differ diff --git a/assets/fonts/Inter-ExtraLight.ttf b/assets/fonts/Inter-ExtraLight.ttf new file mode 100644 index 0000000..64aee30 Binary files /dev/null and b/assets/fonts/Inter-ExtraLight.ttf differ diff --git a/assets/fonts/Inter-Light.ttf b/assets/fonts/Inter-Light.ttf new file mode 100644 index 0000000..9e265d8 Binary files /dev/null and b/assets/fonts/Inter-Light.ttf differ diff --git a/assets/fonts/Inter-Medium.ttf b/assets/fonts/Inter-Medium.ttf new file mode 100644 index 0000000..b53fb1c Binary files /dev/null and b/assets/fonts/Inter-Medium.ttf differ diff --git a/assets/fonts/Inter-Regular.ttf b/assets/fonts/Inter-Regular.ttf new file mode 100644 index 0000000..8d4eebf Binary files /dev/null and b/assets/fonts/Inter-Regular.ttf differ diff --git a/assets/fonts/Inter-SemiBold.ttf b/assets/fonts/Inter-SemiBold.ttf new file mode 100644 index 0000000..c6aeeb1 Binary files /dev/null and b/assets/fonts/Inter-SemiBold.ttf differ diff --git a/assets/fonts/Inter-Thin.ttf b/assets/fonts/Inter-Thin.ttf new file mode 100644 index 0000000..7aed55d Binary files /dev/null and b/assets/fonts/Inter-Thin.ttf differ diff --git a/assets/fonts/Roboto-Bold.ttf b/assets/fonts/Roboto-Bold.ttf new file mode 100644 index 0000000..d998cf5 Binary files /dev/null and b/assets/fonts/Roboto-Bold.ttf differ diff --git a/assets/fonts/Roboto-Medium.ttf b/assets/fonts/Roboto-Medium.ttf new file mode 100644 index 0000000..f714a51 Binary files /dev/null and b/assets/fonts/Roboto-Medium.ttf differ diff --git a/assets/fonts/Roboto-Regular.ttf b/assets/fonts/Roboto-Regular.ttf new file mode 100644 index 0000000..2b6392f Binary files /dev/null and b/assets/fonts/Roboto-Regular.ttf differ diff --git a/assets/fonts/WorkSans-Bold.ttf b/assets/fonts/WorkSans-Bold.ttf new file mode 100644 index 0000000..ce8fe08 Binary files /dev/null and b/assets/fonts/WorkSans-Bold.ttf differ diff --git a/assets/fonts/WorkSans-Medium.ttf b/assets/fonts/WorkSans-Medium.ttf new file mode 100644 index 0000000..112d3a4 Binary files /dev/null and b/assets/fonts/WorkSans-Medium.ttf differ diff --git a/assets/fonts/WorkSans-Regular.ttf b/assets/fonts/WorkSans-Regular.ttf new file mode 100644 index 0000000..b26ace6 Binary files /dev/null and b/assets/fonts/WorkSans-Regular.ttf differ diff --git a/assets/fonts/WorkSans-SemiBold.ttf b/assets/fonts/WorkSans-SemiBold.ttf new file mode 100644 index 0000000..a064002 Binary files /dev/null and b/assets/fonts/WorkSans-SemiBold.ttf differ diff --git a/assets/homescreen/home_1.png b/assets/homescreen/home_1.png new file mode 100644 index 0000000..2fe1364 Binary files /dev/null and b/assets/homescreen/home_1.png differ diff --git a/assets/homescreen/home_2.png b/assets/homescreen/home_2.png new file mode 100644 index 0000000..d9013fd Binary files /dev/null and b/assets/homescreen/home_2.png differ diff --git a/assets/homescreen/home_3.png b/assets/homescreen/home_3.png new file mode 100644 index 0000000..c3706cc Binary files /dev/null and b/assets/homescreen/home_3.png differ diff --git a/assets/icon/icon2.png b/assets/icon/icon2.png new file mode 100644 index 0000000..5204b80 Binary files /dev/null and b/assets/icon/icon2.png differ diff --git a/assets/images/Astronaut.glb b/assets/images/Astronaut.glb new file mode 100644 index 0000000..aa57292 Binary files /dev/null and b/assets/images/Astronaut.glb differ diff --git a/assets/images/Totoro.glb b/assets/images/Totoro.glb new file mode 100644 index 0000000..a14455f Binary files /dev/null and b/assets/images/Totoro.glb differ diff --git a/assets/images/anya.jpg b/assets/images/anya.jpg new file mode 100644 index 0000000..54803b2 Binary files /dev/null and b/assets/images/anya.jpg differ diff --git a/assets/images/apple.png b/assets/images/apple.png new file mode 100644 index 0000000..31fa44e Binary files /dev/null and b/assets/images/apple.png differ diff --git a/assets/images/feedbackImage.png b/assets/images/feedbackImage.png new file mode 100644 index 0000000..6e06f85 Binary files /dev/null and b/assets/images/feedbackImage.png differ diff --git a/assets/images/girl.jpg b/assets/images/girl.jpg new file mode 100644 index 0000000..1b9672e Binary files /dev/null and b/assets/images/girl.jpg differ diff --git a/assets/images/girl_icon.png b/assets/images/girl_icon.png new file mode 100644 index 0000000..221c968 Binary files /dev/null and b/assets/images/girl_icon.png differ diff --git a/assets/images/google.png b/assets/images/google.png new file mode 100644 index 0000000..494aced Binary files /dev/null and b/assets/images/google.png differ diff --git a/assets/images/group.glb b/assets/images/group.glb new file mode 100644 index 0000000..b503858 Binary files /dev/null and b/assets/images/group.glb differ diff --git a/assets/images/group.jpg b/assets/images/group.jpg new file mode 100644 index 0000000..8f6ae93 Binary files /dev/null and b/assets/images/group.jpg differ diff --git a/assets/images/helpImage.png b/assets/images/helpImage.png new file mode 100644 index 0000000..4e0ec4c Binary files /dev/null and b/assets/images/helpImage.png differ diff --git a/assets/images/images.jfif b/assets/images/images.jfif new file mode 100644 index 0000000..939e707 Binary files /dev/null and b/assets/images/images.jfif differ diff --git a/assets/images/inviteImage.png b/assets/images/inviteImage.png new file mode 100644 index 0000000..5ab808a Binary files /dev/null and b/assets/images/inviteImage.png differ diff --git a/assets/images/iu.jpg b/assets/images/iu.jpg new file mode 100644 index 0000000..bd10732 Binary files /dev/null and b/assets/images/iu.jpg differ diff --git a/assets/images/login_image.png b/assets/images/login_image.png new file mode 100644 index 0000000..f6dbcaa Binary files /dev/null and b/assets/images/login_image.png differ diff --git a/assets/images/shirt1.jpg b/assets/images/shirt1.jpg new file mode 100644 index 0000000..8da9693 Binary files /dev/null and b/assets/images/shirt1.jpg differ diff --git a/assets/images/shirt2.jfif b/assets/images/shirt2.jfif new file mode 100644 index 0000000..7a5bd84 Binary files /dev/null and b/assets/images/shirt2.jfif differ diff --git a/assets/images/signup_image.png b/assets/images/signup_image.png new file mode 100644 index 0000000..f61a027 Binary files /dev/null and b/assets/images/signup_image.png differ diff --git a/assets/images/supportIcon.png b/assets/images/supportIcon.png new file mode 100644 index 0000000..5da2d66 Binary files /dev/null and b/assets/images/supportIcon.png differ diff --git a/assets/images/totoroo.jpg b/assets/images/totoroo.jpg new file mode 100644 index 0000000..ea88678 Binary files /dev/null and b/assets/images/totoroo.jpg differ diff --git a/assets/images/userImage.png b/assets/images/userImage.png new file mode 100644 index 0000000..8c25bff Binary files /dev/null and b/assets/images/userImage.png differ diff --git a/assets/images/van.png b/assets/images/van.png new file mode 100644 index 0000000..6edf743 Binary files /dev/null and b/assets/images/van.png differ diff --git a/assets/images/vandyck.glb b/assets/images/vandyck.glb new file mode 100644 index 0000000..6e74da1 Binary files /dev/null and b/assets/images/vandyck.glb differ diff --git a/assets/images/yor.jpg b/assets/images/yor.jpg new file mode 100644 index 0000000..f9552c2 Binary files /dev/null and b/assets/images/yor.jpg differ diff --git a/assets/images/yourwaifu.png b/assets/images/yourwaifu.png new file mode 100644 index 0000000..8c065ee Binary files /dev/null and b/assets/images/yourwaifu.png differ diff --git a/assets/introduction_animation/care_image.png b/assets/introduction_animation/care_image.png new file mode 100644 index 0000000..6137f80 Binary files /dev/null and b/assets/introduction_animation/care_image.png differ diff --git a/assets/introduction_animation/introduction_animation.png b/assets/introduction_animation/introduction_animation.png new file mode 100644 index 0000000..5013b4c Binary files /dev/null and b/assets/introduction_animation/introduction_animation.png differ diff --git a/assets/introduction_animation/introduction_image.png b/assets/introduction_animation/introduction_image.png new file mode 100644 index 0000000..8d1e4d2 Binary files /dev/null and b/assets/introduction_animation/introduction_image.png differ diff --git a/assets/introduction_animation/mood_diary_image.png b/assets/introduction_animation/mood_diary_image.png new file mode 100644 index 0000000..172ff2b Binary files /dev/null and b/assets/introduction_animation/mood_diary_image.png differ diff --git a/assets/introduction_animation/relax_image.png b/assets/introduction_animation/relax_image.png new file mode 100644 index 0000000..e13b132 Binary files /dev/null and b/assets/introduction_animation/relax_image.png differ diff --git a/assets/introduction_animation/welcome_image.png b/assets/introduction_animation/welcome_image.png new file mode 100644 index 0000000..fdd9746 Binary files /dev/null and b/assets/introduction_animation/welcome_image.png differ diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000..e96ef60 --- /dev/null +++ b/ios/.gitignore @@ -0,0 +1,32 @@ +*.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/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..f2872cf --- /dev/null +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 9.0 + + diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..455b543 --- /dev/null +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,512 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1300; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.bestFlutterUiTemplates; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.bestFlutterUiTemplates; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.bestFlutterUiTemplates; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..3db53b6 --- /dev/null +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..70693e4 --- /dev/null +++ b/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..c03c865 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..01c1b47 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..1d7c2dc Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..6d27c9a Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..99cbf1a Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..89949c1 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..609d71a Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..1d7c2dc Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..cb49e14 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..eeeef9b Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png new file mode 100644 index 0000000..88f75c0 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png new file mode 100644 index 0000000..81e008b Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png new file mode 100644 index 0000000..4bd775c Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png new file mode 100644 index 0000000..688d612 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..eeeef9b Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..15670ee Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png new file mode 100644 index 0000000..ef4e8a5 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png new file mode 100644 index 0000000..00938b7 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..8269be6 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..e94bd5c Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..ee8a749 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/GoogleService-Info.plist b/ios/Runner/GoogleService-Info.plist new file mode 100644 index 0000000..d89de26 --- /dev/null +++ b/ios/Runner/GoogleService-Info.plist @@ -0,0 +1,34 @@ + + + + + CLIENT_ID + 977448159531-q7uaga6fq9les4b01tn8kbc1olpvjtmn.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.977448159531-q7uaga6fq9les4b01tn8kbc1olpvjtmn + API_KEY + AIzaSyBh4Wlp5bRuGZbGnwSnxj9OgTKd7WJ-PL8 + GCM_SENDER_ID + 977448159531 + PLIST_VERSION + 1 + BUNDLE_ID + com.example.bestFlutterUiTemplates + PROJECT_ID + ecoar-2c526 + STORAGE_BUCKET + ecoar-2c526.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:977448159531:ios:47bfd559d696d75cfb1d6e + + \ No newline at end of file diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist new file mode 100644 index 0000000..07b992c --- /dev/null +++ b/ios/Runner/Info.plist @@ -0,0 +1,65 @@ + + + + + + +CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + + + com.googleusercontent.apps.977448159531-q7uaga6fq9les4b01tn8kbc1olpvjtmn + + + + + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Best Flutter UI Templates + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + best_flutter_ui_templates + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/ios/firebase_app_id_file.json b/ios/firebase_app_id_file.json new file mode 100644 index 0000000..891e2f0 --- /dev/null +++ b/ios/firebase_app_id_file.json @@ -0,0 +1,7 @@ +{ + "file_generated_by": "FlutterFire CLI", + "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", + "GOOGLE_APP_ID": "1:977448159531:ios:47bfd559d696d75cfb1d6e", + "FIREBASE_PROJECT_ID": "ecoar-2c526", + "GCM_SENDER_ID": "977448159531" +} \ No newline at end of file diff --git a/lib/app_theme.dart b/lib/app_theme.dart new file mode 100644 index 0000000..0946edc --- /dev/null +++ b/lib/app_theme.dart @@ -0,0 +1,89 @@ +import 'package:flutter/material.dart'; + +class AppTheme { + AppTheme._(); + + static const Color notWhite = Color(0xFFEDF0F2); + static const Color nearlyWhite = Color(0xFFFEFEFE); + static const Color white = Color(0xFFFFFFFF); + static const Color nearlyBlack = Color(0xFF213333); + static const Color grey = Color(0xFF3A5160); + static const Color dark_grey = Color(0xFF313A44); + + static const Color darkText = Color(0xFF253840); + static const Color darkerText = Color(0xFF17262A); + static const Color lightText = Color(0xFF4A6572); + static const Color deactivatedText = Color(0xFF767676); + static const Color dismissibleBackground = Color(0xFF364A54); + static const Color chipBackground = Color(0xFFEEF1F3); + static const Color spacer = Color(0xFFF2F2F2); + static const String fontName = 'WorkSans'; + + static const TextTheme textTheme = TextTheme( + headline4: display1, + headline5: headline, + headline6: title, + subtitle2: subtitle, + bodyText2: body2, + bodyText1: body1, + caption: caption, + ); + + static const TextStyle display1 = TextStyle( // h4 -> display1 + fontFamily: fontName, + fontWeight: FontWeight.bold, + fontSize: 36, + letterSpacing: 0.4, + height: 0.9, + color: darkerText, + ); + + static const TextStyle headline = TextStyle( // h5 -> headline + fontFamily: fontName, + fontWeight: FontWeight.bold, + fontSize: 24, + letterSpacing: 0.27, + color: darkerText, + ); + + static const TextStyle title = TextStyle( // h6 -> title + fontFamily: fontName, + fontWeight: FontWeight.bold, + fontSize: 16, + letterSpacing: 0.18, + color: darkerText, + ); + + static const TextStyle subtitle = TextStyle( // subtitle2 -> subtitle + fontFamily: fontName, + fontWeight: FontWeight.w400, + fontSize: 14, + letterSpacing: -0.04, + color: darkText, + ); + + static const TextStyle body2 = TextStyle( // body1 -> body2 + fontFamily: fontName, + fontWeight: FontWeight.w400, + fontSize: 14, + letterSpacing: 0.2, + color: darkText, + ); + + static const TextStyle body1 = TextStyle( // body2 -> body1 + fontFamily: fontName, + fontWeight: FontWeight.w400, + fontSize: 16, + letterSpacing: -0.05, + color: darkText, + ); + + static const TextStyle caption = TextStyle( // Caption -> caption + fontFamily: fontName, + fontWeight: FontWeight.w400, + fontSize: 12, + letterSpacing: 0.2, + color: lightText, // was lightText + ); + +} diff --git a/lib/arcore_app/arcore_screen.dart b/lib/arcore_app/arcore_screen.dart new file mode 100644 index 0000000..7d45bf8 --- /dev/null +++ b/lib/arcore_app/arcore_screen.dart @@ -0,0 +1,59 @@ +import 'package:flutter/material.dart'; +import 'package:arcore_flutter_plugin/arcore_flutter_plugin.dart'; +import 'package:model_viewer_plus/model_viewer_plus.dart'; + +class ArCoreApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter AR', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + // home: ArCoreScreen( + // title: 'Flutter AR', + // ), + home: ModelViewer( + src: "assets/images/Astronaut.glb", + alt: "A 3D model of an Astronaut", + ar: true, + autoRotate: true, + cameraControls: true, + ), + ); + } +} + +class ArCoreScreen extends StatefulWidget { + ArCoreScreen({Key? key, required this.title}) : super(key: key); + final String title; + + @override + _ArCoreAppState createState() => _ArCoreAppState(); +} + +class _ArCoreAppState extends State { + late ArCoreController arCoreController; + + _onArCoreViewCreated(ArCoreController _arcoreController) { + arCoreController = _arcoreController; + } + + @override + void dispose() { + arCoreController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + ), + body: ArCoreView( + onArCoreViewCreated: _onArCoreViewCreated, + ), + ); + } +} diff --git a/lib/custom_drawer/drawer_user_controller.dart b/lib/custom_drawer/drawer_user_controller.dart new file mode 100644 index 0000000..7ef35e5 --- /dev/null +++ b/lib/custom_drawer/drawer_user_controller.dart @@ -0,0 +1,225 @@ +import 'package:best_flutter_ui_templates/app_theme.dart'; +import 'package:best_flutter_ui_templates/custom_drawer/home_drawer.dart'; +import 'package:flutter/material.dart'; + +class DrawerUserController extends StatefulWidget { + const DrawerUserController({ + Key? key, + this.drawerWidth = 250, + this.onDrawerCall, + this.screenView, + this.animatedIconData = AnimatedIcons.arrow_menu, + this.menuView, + this.drawerIsOpen, + this.screenIndex, + }) : super(key: key); + + final double drawerWidth; + final Function(DrawerIndex)? onDrawerCall; + final Widget? screenView; + final Function(bool)? drawerIsOpen; + final AnimatedIconData? animatedIconData; + final Widget? menuView; + final DrawerIndex? screenIndex; + + @override + _DrawerUserControllerState createState() => _DrawerUserControllerState(); +} + +class _DrawerUserControllerState extends State + with TickerProviderStateMixin { + ScrollController? scrollController; + AnimationController? iconAnimationController; + AnimationController? animationController; + + double scrolloffset = 0.0; + + @override + void initState() { + animationController = AnimationController( + duration: const Duration(milliseconds: 2000), vsync: this); + iconAnimationController = AnimationController( + vsync: this, duration: const Duration(milliseconds: 0)); + iconAnimationController + ?..animateTo(1.0, + duration: const Duration(milliseconds: 0), + curve: Curves.fastOutSlowIn); + scrollController = + ScrollController(initialScrollOffset: widget.drawerWidth); + scrollController! + ..addListener(() { + if (scrollController!.offset <= 0) { + if (scrolloffset != 1.0) { + setState(() { + scrolloffset = 1.0; + try { + widget.drawerIsOpen!(true); + } catch (_) {} + }); + } + iconAnimationController?.animateTo(0.0, + duration: const Duration(milliseconds: 0), + curve: Curves.fastOutSlowIn); + } else if (scrollController!.offset > 0 && + scrollController!.offset < widget.drawerWidth.floor()) { + iconAnimationController?.animateTo( + (scrollController!.offset * 100 / (widget.drawerWidth)) / 100, + duration: const Duration(milliseconds: 0), + curve: Curves.fastOutSlowIn); + } else { + if (scrolloffset != 0.0) { + setState(() { + scrolloffset = 0.0; + try { + widget.drawerIsOpen!(false); + } catch (_) {} + }); + } + iconAnimationController?.animateTo(1.0, + duration: const Duration(milliseconds: 0), + curve: Curves.fastOutSlowIn); + } + }); + WidgetsBinding.instance.addPostFrameCallback((_) => getInitState()); + super.initState(); + } + + Future getInitState() async { + scrollController?.jumpTo( + widget.drawerWidth, + ); + return true; + } + + @override + Widget build(BuildContext context) { + var brightness = MediaQuery.of(context).platformBrightness; + bool isLightMode = brightness == Brightness.light; + return Scaffold( + backgroundColor: isLightMode ? AppTheme.white : Color(0xFF408D4D), + body: SingleChildScrollView( + controller: scrollController, + scrollDirection: Axis.horizontal, + physics: const PageScrollPhysics(parent: ClampingScrollPhysics()), + child: SizedBox( + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width + widget.drawerWidth, + //we use with as screen width and add drawerWidth (from navigation_home_screen) + child: Row( + children: [ + SizedBox( + width: widget.drawerWidth, + //we divided first drawer Width with HomeDrawer and second full-screen Width with all home screen, we called screen View + height: MediaQuery.of(context).size.height, + child: AnimatedBuilder( + animation: iconAnimationController!, + builder: (BuildContext context, Widget? child) { + return Transform( + //transform we use for the stable drawer we, not need to move with scroll view + transform: Matrix4.translationValues( + scrollController!.offset, 0.0, 0.0), + child: HomeDrawer( + screenIndex: widget.screenIndex == null + ? DrawerIndex.HOME + : widget.screenIndex, + iconAnimationController: iconAnimationController, + callBackIndex: (DrawerIndex indexType) { + onDrawerClick(); + try { + widget.onDrawerCall!(indexType); + } catch (e) {} + }, + ), + ); + }, + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + //full-screen Width with widget.screenView + child: Container( + decoration: BoxDecoration( + color: AppTheme.white, + boxShadow: [ + BoxShadow( + color: AppTheme.grey.withOpacity(0.6), + blurRadius: 24), + ], + ), + child: Stack( + children: [ + //this IgnorePointer we use as touch(user Interface) widget.screen View, for example scrolloffset == 1 means drawer is close we just allow touching all widget.screen View + IgnorePointer( + ignoring: scrolloffset == 1 || false, + child: widget.screenView, + ), + //alternative touch(user Interface) for widget.screen, for example, drawer is close we need to tap on a few home screen area and close the drawer + if (scrolloffset == 1.0) + InkWell( + onTap: () { + onDrawerClick(); + }, + ), + // this just menu and arrow icon animation + Padding( + padding: EdgeInsets.only( + top: MediaQuery.of(context).padding.top + 8, + left: 8), + child: SizedBox( + width: AppBar().preferredSize.height - 8, + height: AppBar().preferredSize.height - 8, + child: Material( + color: Colors.transparent, + child: InkWell( + borderRadius: BorderRadius.circular( + AppBar().preferredSize.height), + child: Center( + // if you use your own menu view UI you add form initialization + child: widget.menuView != null + ? widget.menuView + : AnimatedIcon( + color: isLightMode + ? AppTheme.dark_grey + : AppTheme.nearlyBlack, + icon: widget.animatedIconData ?? + AnimatedIcons.arrow_menu, + progress: iconAnimationController!), + ), + onTap: () { + FocusScope.of(context) + .requestFocus(FocusNode()); + onDrawerClick(); + }, + ), + ), + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ); + } + + void onDrawerClick() { + //if scrollcontroller.offset != 0.0 then we set to closed the drawer(with animation to offset zero position) if is not 1 then open the drawer + if (scrollController!.offset != 0.0) { + scrollController?.animateTo( + 0.0, + duration: const Duration(milliseconds: 400), + curve: Curves.fastOutSlowIn, + ); + } else { + scrollController?.animateTo( + widget.drawerWidth, + duration: const Duration(milliseconds: 400), + curve: Curves.fastOutSlowIn, + ); + } + } +} diff --git a/lib/custom_drawer/home_drawer.dart b/lib/custom_drawer/home_drawer.dart new file mode 100644 index 0000000..2d18b66 --- /dev/null +++ b/lib/custom_drawer/home_drawer.dart @@ -0,0 +1,329 @@ +import 'package:best_flutter_ui_templates/app_theme.dart'; +import 'package:best_flutter_ui_templates/login/pages/signup_page.dart'; +import 'package:best_flutter_ui_templates/login/services/auth_service.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; + +class HomeDrawer extends StatefulWidget { + HomeDrawer( + {Key? key, + this.screenIndex, + this.iconAnimationController, + this.callBackIndex}) + : super(key: key); + + final AnimationController? iconAnimationController; + final DrawerIndex? screenIndex; + final Function(DrawerIndex)? callBackIndex; + + @override + _HomeDrawerState createState() => _HomeDrawerState(); +} + +class _HomeDrawerState extends State { + List? drawerList; + @override + void initState() { + setDrawerListArray(); + super.initState(); + } + + void setDrawerListArray() { + drawerList = [ + DrawerList( + index: DrawerIndex.HOME, + labelName: 'Home', + icon: Icon(Icons.home), + ), + DrawerList( + index: DrawerIndex.Help, + labelName: 'Shopping', + isAssetsImage: true, + imageName: 'assets/images/supportIcon.png', + ), + DrawerList( + index: DrawerIndex.FeedBack, + labelName: 'Waifu Type', + icon: Icon(Icons.help), + ), + DrawerList( + index: DrawerIndex.Invite, + labelName: 'About Us', + icon: Icon(Icons.info), + ), + ]; + } + + @override + Widget build(BuildContext context) { + var brightness = MediaQuery.of(context).platformBrightness; + bool isLightMode = brightness == Brightness.light; + final user = FirebaseAuth.instance.currentUser; + if (user != null) { + print(user.uid); + } + return Scaffold( + backgroundColor: AppTheme.notWhite.withOpacity(0.5), + body: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + width: double.infinity, + padding: const EdgeInsets.only(top: 40.0), + child: Container( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + AnimatedBuilder( + animation: widget.iconAnimationController!, + builder: (BuildContext context, Widget? child) { + return ScaleTransition( + scale: AlwaysStoppedAnimation(1.0 - + (widget.iconAnimationController!.value) * 0.2), + child: RotationTransition( + turns: AlwaysStoppedAnimation(Tween( + begin: 0.0, end: 24.0) + .animate(CurvedAnimation( + parent: widget.iconAnimationController!, + curve: Curves.fastOutSlowIn)) + .value / + 360), + child: Container( + height: 120, + width: 120, + decoration: BoxDecoration( + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + color: Color.fromARGB(255, 203, 237, 67) + .withOpacity(0.6), + offset: const Offset(2.0, 4.0), + blurRadius: 8), + ], + ), + child: ClipRRect( + borderRadius: + const BorderRadius.all(Radius.circular(60.0)), + child: Image.asset('assets/images/girl_icon.png'), + ), + ), + ), + ); + }, + ), + Padding( + padding: const EdgeInsets.only( + top: 8, + left: 4, + ), + child: Text( + (user?.email ?? ''), + style: TextStyle( + fontWeight: FontWeight.w600, + color: isLightMode + ? AppTheme.grey + : Color.fromARGB(255, 248, 233, 220), + fontSize: 14, + ), + ), + ), + ], + ), + ), + ), + const SizedBox( + height: 4, + ), + Divider( + height: 1, + color: AppTheme.grey.withOpacity(0.6), + ), + Expanded( + child: ListView.builder( + physics: const BouncingScrollPhysics(), + padding: const EdgeInsets.all(0.0), + itemCount: drawerList?.length, + itemBuilder: (BuildContext context, int index) { + return inkwell(drawerList![index]); + }, + ), + ), + Divider( + height: 1, + color: AppTheme.grey.withOpacity(0.6), + ), + Column( + children: [ + ListTile( + title: Text( + 'Sign Out', + style: TextStyle( + fontFamily: AppTheme.fontName, + fontWeight: FontWeight.w600, + fontSize: 16, + color: AppTheme.darkText, + ), + textAlign: TextAlign.left, + ), + trailing: Icon( + Icons.power_settings_new, + color: Color.fromARGB(255, 225, 82, 72), + ), + onTap: () { + onTapped(); + }, + ), + SizedBox( + height: MediaQuery.of(context).padding.bottom, + ) + ], + ), + ], + ), + ); + } + + void onTapped() async { + await FirebaseAuth.instance.signOut(); + await AuthService().signOutWithGoogle(); + Navigator.push( + context, + MaterialPageRoute(builder: (context) => SignupPage()), + ); + } + + Widget inkwell(DrawerList listData) { + return Material( + color: Colors.transparent, + child: InkWell( + splashColor: Colors.grey.withOpacity(0.1), + highlightColor: Colors.transparent, + onTap: () { + navigationtoScreen(listData.index!); + }, + child: Stack( + children: [ + Container( + padding: const EdgeInsets.only(top: 8.0, bottom: 8.0), + child: Row( + children: [ + Container( + width: 6.0, + height: 46.0, + // decoration: BoxDecoration( + // color: widget.screenIndex == listData.index + // ? Colors.blue + // : Colors.transparent, + // borderRadius: new BorderRadius.only( + // topLeft: Radius.circular(0), + // topRight: Radius.circular(16), + // bottomLeft: Radius.circular(0), + // bottomRight: Radius.circular(16), + // ), + // ), + ), + const Padding( + padding: EdgeInsets.all(4.0), + ), + listData.isAssetsImage + ? Container( + width: 24, + height: 24, + child: Image.asset(listData.imageName, + color: widget.screenIndex == listData.index + ? Colors.blue + : AppTheme.nearlyBlack), + ) + : Icon(listData.icon?.icon, + color: widget.screenIndex == listData.index + ? Colors.blue + : AppTheme.nearlyBlack), + const Padding( + padding: EdgeInsets.all(4.0), + ), + Text( + listData.labelName, + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 16, + color: widget.screenIndex == listData.index + ? Colors.black + : AppTheme.nearlyBlack, + ), + textAlign: TextAlign.left, + ), + ], + ), + ), + widget.screenIndex == listData.index + ? AnimatedBuilder( + animation: widget.iconAnimationController!, + builder: (BuildContext context, Widget? child) { + return Transform( + transform: Matrix4.translationValues( + (MediaQuery.of(context).size.width * 0.75 - 64) * + (1.0 - + widget.iconAnimationController!.value - + 1.0), + 0.0, + 0.0), + child: Padding( + padding: EdgeInsets.only(top: 8, bottom: 8), + child: Container( + width: + MediaQuery.of(context).size.width * 0.75 - 64, + height: 46, + decoration: BoxDecoration( + color: Colors.blue.withOpacity(0.2), + borderRadius: new BorderRadius.only( + topLeft: Radius.circular(0), + topRight: Radius.circular(28), + bottomLeft: Radius.circular(0), + bottomRight: Radius.circular(28), + ), + ), + ), + ), + ); + }, + ) + : const SizedBox() + ], + ), + ), + ); + } + + Future navigationtoScreen(DrawerIndex indexScreen) async { + widget.callBackIndex!(indexScreen); + } +} + +enum DrawerIndex { + HOME, + FeedBack, + Help, + Share, + About, + Invite, + Testing, +} + +class DrawerList { + DrawerList({ + this.isAssetsImage = false, + this.labelName = '', + this.icon, + this.index, + this.imageName = '', + }); + + String labelName; + Icon? icon; + bool isAssetsImage; + String imageName; + DrawerIndex? index; +} diff --git a/lib/feedback_screen.dart b/lib/feedback_screen.dart new file mode 100644 index 0000000..7bcd96e --- /dev/null +++ b/lib/feedback_screen.dart @@ -0,0 +1,129 @@ +import 'package:best_flutter_ui_templates/app_theme.dart'; +import 'package:flutter/material.dart'; + +class FeedbackScreen extends StatefulWidget { + @override + _FeedbackScreenState createState() => _FeedbackScreenState(); +} + +class _FeedbackScreenState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + var brightness = MediaQuery.of(context).platformBrightness; + bool isLightMode = brightness == Brightness.light; + return SingleChildScrollView( + child: Column( + children: [ + Container( + padding: EdgeInsets.only( + top: MediaQuery.of(context).padding.top, left: 16, right: 16), + child: Image.asset('assets/images/iu.jpg'), + ), + Container( + padding: const EdgeInsets.only(top: 8), + child: Text( + '', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: isLightMode ? Colors.black : Colors.white), + ), + ), + Container( + padding: EdgeInsets.only( + top: MediaQuery.of(context).padding.top, left: 16, right: 16), + child: Image.asset('assets/images/anya.jpg'), + ), + Container( + padding: const EdgeInsets.only(top: 8), + child: Text( + '', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: isLightMode ? Colors.black : Colors.white), + ), + ), + Container( + padding: EdgeInsets.only( + top: MediaQuery.of(context).padding.top, left: 16, right: 16), + child: Image.asset('assets/images/yor.jpg'), + ), + Container( + padding: const EdgeInsets.only(top: 8), + child: Text( + '', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: isLightMode ? Colors.black : Colors.white), + ), + ), + Container( + padding: EdgeInsets.only( + top: MediaQuery.of(context).padding.top, left: 16, right: 16), + child: Image.asset('assets/images/van.png'), + ), + Container( + padding: const EdgeInsets.only(top: 8), + child: Text( + '', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: isLightMode ? Colors.black : Colors.white), + ), + ), + ], + ), + ); + } + + Widget _buildComposer() { + return Padding( + padding: const EdgeInsets.only(top: 16, left: 32, right: 32), + child: Container( + decoration: BoxDecoration( + color: AppTheme.white, + borderRadius: BorderRadius.circular(8), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.8), + offset: const Offset(4, 4), + blurRadius: 8), + ], + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(25), + child: Container( + padding: const EdgeInsets.all(4.0), + constraints: const BoxConstraints(minHeight: 80, maxHeight: 160), + color: AppTheme.white, + child: SingleChildScrollView( + padding: + const EdgeInsets.only(left: 10, right: 10, top: 0, bottom: 0), + child: TextField( + maxLines: null, + onChanged: (String txt) {}, + style: TextStyle( + fontFamily: AppTheme.fontName, + fontSize: 16, + color: AppTheme.dark_grey, + ), + cursorColor: Colors.blue, + decoration: InputDecoration( + border: InputBorder.none, + hintText: 'Enter your feedback...'), + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/firebase_options.dart b/lib/firebase_options.dart new file mode 100644 index 0000000..cdc2db8 --- /dev/null +++ b/lib/firebase_options.dart @@ -0,0 +1,69 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for web - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions android = FirebaseOptions( + apiKey: 'AIzaSyDwToAGeuW3NI8qnfHoTlj2LRXuGHyfwq4', + appId: '1:977448159531:android:8b62a3f33493580cfb1d6e', + messagingSenderId: '977448159531', + projectId: 'ecoar-2c526', + storageBucket: 'ecoar-2c526.appspot.com', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: 'AIzaSyBh4Wlp5bRuGZbGnwSnxj9OgTKd7WJ-PL8', + appId: '1:977448159531:ios:47bfd559d696d75cfb1d6e', + messagingSenderId: '977448159531', + projectId: 'ecoar-2c526', + storageBucket: 'ecoar-2c526.appspot.com', + iosClientId: '977448159531-q7uaga6fq9les4b01tn8kbc1olpvjtmn.apps.googleusercontent.com', + iosBundleId: 'com.example.bestFlutterUiTemplates', + ); +} diff --git a/lib/help_screen.dart b/lib/help_screen.dart new file mode 100644 index 0000000..49c1771 --- /dev/null +++ b/lib/help_screen.dart @@ -0,0 +1,71 @@ +import 'package:best_flutter_ui_templates/app_theme.dart'; +import 'package:flutter/material.dart'; + +class HelpScreen extends StatefulWidget { + @override + _HelpScreenState createState() => _HelpScreenState(); +} + +class _HelpScreenState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + var brightness = MediaQuery.of(context).platformBrightness; + bool isLightMode = brightness == Brightness.light; + return SingleChildScrollView( + child: Column( + children: [ + Container( + padding: EdgeInsets.only( + top: MediaQuery.of(context).padding.top, left: 16, right: 16), + child: Image.asset('assets/images/shirt2.jfif'), + ), + Container( + padding: const EdgeInsets.only(top: 8), + child: Text( + 'RM50', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: isLightMode ? Colors.black : Colors.white), + ), + ), + Container( + padding: EdgeInsets.only( + top: MediaQuery.of(context).padding.top, left: 16, right: 16), + child: Image.asset('assets/images/shirt1.jpg'), + ), + Container( + padding: const EdgeInsets.only(top: 8), + child: Text( + 'RM40', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: isLightMode ? Colors.black : Colors.white), + ), + ), + Container( + padding: EdgeInsets.only( + top: MediaQuery.of(context).padding.top, left: 16, right: 16), + child: Image.asset('assets/images/images.jfif'), + ), + Container( + padding: const EdgeInsets.only(top: 8), + child: Text( + 'RM900', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: isLightMode ? Colors.black : Colors.white), + ), + ), + ], + ), + ); + } +} diff --git a/lib/home__screen/home_app_theme.dart b/lib/home__screen/home_app_theme.dart new file mode 100644 index 0000000..5ee0fc5 --- /dev/null +++ b/lib/home__screen/home_app_theme.dart @@ -0,0 +1,51 @@ +import 'package:best_flutter_ui_templates/main.dart'; +import 'package:flutter/material.dart'; + +class HomeAppTheme { + static TextTheme _buildTextTheme(TextTheme base) { + const String fontName = 'WorkSans'; + return base.copyWith( + headline1: base.headline1?.copyWith(fontFamily: fontName), + headline2: base.headline2?.copyWith(fontFamily: fontName), + headline3: base.headline3?.copyWith(fontFamily: fontName), + headline4: base.headline4?.copyWith(fontFamily: fontName), + headline5: base.headline5?.copyWith(fontFamily: fontName), + headline6: base.headline6?.copyWith(fontFamily: fontName), + button: base.button?.copyWith(fontFamily: fontName), + caption: base.caption?.copyWith(fontFamily: fontName), + bodyText1: base.bodyText1?.copyWith(fontFamily: fontName), + bodyText2: base.bodyText2?.copyWith(fontFamily: fontName), + subtitle1: base.subtitle1?.copyWith(fontFamily: fontName), + subtitle2: base.subtitle2?.copyWith(fontFamily: fontName), + overline: base.overline?.copyWith(fontFamily: fontName), + ); + } + + static ThemeData buildLightTheme() { + final Color primaryColor = HexColor('#54D3C2'); + final Color secondaryColor = HexColor('#54D3C2'); + final ColorScheme colorScheme = const ColorScheme.light().copyWith( + primary: primaryColor, + secondary: secondaryColor, + ); + final ThemeData base = ThemeData.light(); + return base.copyWith( + colorScheme: colorScheme, + primaryColor: primaryColor, + indicatorColor: Colors.white, + splashColor: Colors.white24, + splashFactory: InkRipple.splashFactory, + canvasColor: Colors.white, + backgroundColor: const Color(0xFFFFFFFF), + scaffoldBackgroundColor: const Color(0xFFF6F6F6), + errorColor: const Color(0xFFB00020), + buttonTheme: ButtonThemeData( + colorScheme: colorScheme, + textTheme: ButtonTextTheme.primary, + ), + textTheme: _buildTextTheme(base.textTheme), + primaryTextTheme: _buildTextTheme(base.primaryTextTheme), + platform: TargetPlatform.iOS, + ); + } +} diff --git a/lib/home__screen/home_list_view.dart b/lib/home__screen/home_list_view.dart new file mode 100644 index 0000000..223a9be --- /dev/null +++ b/lib/home__screen/home_list_view.dart @@ -0,0 +1,240 @@ +import 'package:best_flutter_ui_templates/arcore_app/arcore_screen.dart'; +import 'package:best_flutter_ui_templates/home__screen/home_app_theme.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; + + +import 'model/home_list_data.dart'; + +class HomeListView extends StatelessWidget { + const HomeListView( + {Key? key, + this.homeData, + this.animationController, + this.animation, + this.callback}) + : super(key: key); + + final VoidCallback? callback; + final HomeListData? homeData; + final AnimationController? animationController; + final Animation? animation; + + @override + Widget build(BuildContext context) { + return AnimatedBuilder( + animation: animationController!, + builder: (BuildContext context, Widget? child) { + return FadeTransition( + opacity: animation!, + child: Transform( + transform: Matrix4.translationValues( + 0.0, 50 * (1.0 - animation!.value), 0.0), + child: Padding( + padding: const EdgeInsets.only( + left: 24, right: 24, top: 8, bottom: 16), + child: InkWell( + splashColor: Colors.transparent, + onTap: callback, + child: Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(16.0)), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.6), + offset: const Offset(4, 4), + blurRadius: 16, + ), + ], + ), + child: ClipRRect( + borderRadius: const BorderRadius.all(Radius.circular(16.0)), + child: Stack( + children: [ + Column( + children: [ + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ArCoreApp()), + ); + }, + child: AspectRatio( + aspectRatio: 2, + child: Image.asset( + homeData!.imagePath, + fit: BoxFit.cover, + ), + ), + ), + Container( + color: HomeAppTheme.buildLightTheme() + .backgroundColor, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Container( + child: Padding( + padding: const EdgeInsets.only( + left: 8, top: 8, bottom: 8), + child: Column( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + homeData!.titleTxt, + textAlign: TextAlign.left, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 22, + ), + ), + Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.symmetric( + vertical: 10.0, + ), + child: Text( + homeData!.subTxt, + style: TextStyle( + fontSize: 14, + color: Colors.grey + .withOpacity(0.8), + ), + ), + ), + const SizedBox( + width: 4, + ), + ], + ), + Padding( + padding: + const EdgeInsets.only(top: 4), + child: Row( + children: [ + RatingBar( + initialRating: + homeData!.rating, + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 24, + ratingWidget: RatingWidget( + full: Icon( + Icons.star_rate_rounded, + color: HomeAppTheme + .buildLightTheme() + .primaryColor, + ), + half: Icon( + Icons.star_half_rounded, + color: HomeAppTheme + .buildLightTheme() + .primaryColor, + ), + empty: Icon( + Icons + .star_border_rounded, + color: HomeAppTheme + .buildLightTheme() + .primaryColor, + ), + ), + itemPadding: + EdgeInsets.zero, + onRatingUpdate: (rating) { + print(rating); + }, + ), + Text( + ' ${homeData!.reviews} Reviews', + style: TextStyle( + fontSize: 14, + color: Colors.grey + .withOpacity(0.8)), + ), + ], + ), + ), + ], + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only( + right: 16, top: 8), + child: Column( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.end, + children: [ + Text( + '${homeData!.perNight}', + textAlign: TextAlign.left, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 22, + ), + ), + Text( + '', + style: TextStyle( + fontSize: 14, + color: + Colors.grey.withOpacity(0.8)), + ), + ], + ), + ), + ], + ), + ), + ], + ), + Positioned( + top: 8, + right: 8, + child: Material( + color: Colors.transparent, + child: InkWell( + borderRadius: const BorderRadius.all( + Radius.circular(32.0), + ), + onTap: () {}, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Icon( + Icons.favorite_border, + color: HomeAppTheme.buildLightTheme() + .primaryColor, + ), + ), + ), + ), + ) + ], + ), + ), + ), + ), + ), + ), + ); + }, + ); + } +} diff --git a/lib/home__screen/home_screen_secodary.dart b/lib/home__screen/home_screen_secodary.dart new file mode 100644 index 0000000..09e7436 --- /dev/null +++ b/lib/home__screen/home_screen_secodary.dart @@ -0,0 +1,370 @@ +import 'package:best_flutter_ui_templates/home__screen/home_list_view.dart'; +import 'package:best_flutter_ui_templates/home__screen/leaderboard.dart'; +import 'package:best_flutter_ui_templates/home__screen/model/home_list_data.dart'; +import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:intl/intl.dart'; +import 'home_app_theme.dart'; + +class HomeScreen extends StatefulWidget { + @override + _HomeScreenState createState() => _HomeScreenState(); +} + +class _HomeScreenState extends State with TickerProviderStateMixin { + AnimationController? animationController; + List homeList = HomeListData.homeList; + final ScrollController _scrollController = ScrollController(); + + DateTime startDate = DateTime.now(); + DateTime endDate = DateTime.now().add(const Duration(days: 5)); + + @override + void initState() { + animationController = AnimationController( + duration: const Duration(milliseconds: 1000), vsync: this); + super.initState(); + } + + Future getData() async { + await Future.delayed(const Duration(milliseconds: 200)); + return true; + } + + @override + void dispose() { + animationController?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Theme( + data: HomeAppTheme.buildLightTheme(), + child: Container( + child: Scaffold( + body: Stack( + children: [ + InkWell( + splashColor: Colors.transparent, + focusColor: Colors.transparent, + highlightColor: Colors.transparent, + hoverColor: Colors.transparent, + onTap: () { + FocusScope.of(context).requestFocus(FocusNode()); + }, + child: Column( + children: [ + getAppBarUI(), + Expanded( + child: NestedScrollView( + controller: _scrollController, + headerSliverBuilder: + (BuildContext context, bool innerBoxIsScrolled) { + return [ + SliverList( + delegate: SliverChildBuilderDelegate( + (BuildContext context, int index) { + return Column( + children: [ + getSearchBarUI(), + ], + ); + }, childCount: 1), + ), + ]; + }, + body: Container( + color: HomeAppTheme.buildLightTheme().backgroundColor, + child: ListView.builder( + itemCount: homeList.length, + padding: const EdgeInsets.only(top: 8), + scrollDirection: Axis.vertical, + itemBuilder: (BuildContext context, int index) { + final int count = + homeList.length > 10 ? 10 : homeList.length; + final Animation animation = + Tween(begin: 0.0, end: 1.0).animate( + CurvedAnimation( + parent: animationController!, + curve: Interval( + (1 / count) * index, 1.0, + curve: Curves.fastOutSlowIn))); + animationController?.forward(); + return HomeListView( + callback: () {}, + homeData: homeList[index], + animation: animation, + animationController: animationController!, + ); + }, + ), + ), + ), + ) + ], + ), + ), + ], + ), + ), + ), + ); + } + + Widget getListUI() { + return Container( + decoration: BoxDecoration( + color: HomeAppTheme.buildLightTheme().backgroundColor, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.2), + offset: const Offset(0, -2), + blurRadius: 8.0), + ], + ), + child: Column( + children: [ + Container( + height: MediaQuery.of(context).size.height - 156 - 50, + child: FutureBuilder( + future: getData(), + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (!snapshot.hasData) { + return const SizedBox(); + } else { + return ListView.builder( + itemCount: homeList.length, + scrollDirection: Axis.vertical, + itemBuilder: (BuildContext context, int index) { + final int count = + homeList.length > 10 ? 10 : homeList.length; + final Animation animation = + Tween(begin: 0.0, end: 1.0).animate( + CurvedAnimation( + parent: animationController!, + curve: Interval((1 / count) * index, 1.0, + curve: Curves.fastOutSlowIn))); + animationController?.forward(); + + return HomeListView( + callback: () {}, + homeData: homeList[index], + animation: animation, + animationController: animationController!, + ); + }, + ); + } + }, + ), + ) + ], + ), + ); + } + + Widget gethomeViewList() { + final List homeListViews = []; + for (int i = 0; i < homeList.length; i++) { + final int count = homeList.length; + final Animation animation = + Tween(begin: 0.0, end: 1.0).animate( + CurvedAnimation( + parent: animationController!, + curve: Interval((1 / count) * i, 1.0, curve: Curves.fastOutSlowIn), + ), + ); + homeListViews.add( + HomeListView( + callback: () {}, + homeData: homeList[i], + animation: animation, + animationController: animationController!, + ), + ); + } + animationController?.forward(); + return Column( + children: homeListViews, + ); + } + + Widget getSearchBarUI() { + return Padding( + padding: const EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 8), + child: Row( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.only(right: 16, top: 8, bottom: 8), + child: Container( + decoration: BoxDecoration( + color: HomeAppTheme.buildLightTheme().backgroundColor, + borderRadius: const BorderRadius.all( + Radius.circular(38.0), + ), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.2), + offset: const Offset(0, 2), + blurRadius: 8.0), + ], + ), + child: Padding( + padding: const EdgeInsets.only( + left: 16, right: 16, top: 4, bottom: 4), + child: TextField( + onChanged: (String txt) {}, + style: const TextStyle( + fontSize: 18, + ), + cursorColor: HomeAppTheme.buildLightTheme().primaryColor, + decoration: InputDecoration( + border: InputBorder.none, + hintText: 'Search for a waifu..', + ), + ), + ), + ), + ), + ), + Container( + decoration: BoxDecoration( + color: HomeAppTheme.buildLightTheme().primaryColor, + borderRadius: const BorderRadius.all( + Radius.circular(38.0), + ), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.4), + offset: const Offset(0, 2), + blurRadius: 8.0), + ], + ), + child: Material( + color: Colors.transparent, + child: InkWell( + borderRadius: const BorderRadius.all( + Radius.circular(32.0), + ), + onTap: () { + FocusScope.of(context).requestFocus(FocusNode()); + }, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Icon(FontAwesomeIcons.magnifyingGlass, + size: 20, + color: HomeAppTheme.buildLightTheme().backgroundColor), + ), + ), + ), + ), + ], + ), + ); + } + + Widget getAppBarUI() { + return Container( + decoration: BoxDecoration( + color: HomeAppTheme.buildLightTheme().backgroundColor, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.2), + offset: const Offset(0, 2), + blurRadius: 8.0, + ), + ], + ), + child: Padding( + padding: EdgeInsets.only( + top: MediaQuery.of(context).padding.top, left: 8, right: 8), + child: Row( + children: [ + Container( + alignment: Alignment.centerLeft, + width: AppBar().preferredSize.height + 40, + height: AppBar().preferredSize.height, + child: Material( + color: Colors.transparent, + //Appbar navigation + ), + ), + Expanded( + child: Center( + child: Text( + 'MyWaifu', + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 22, + ), + ), + ), + ), + Container( + width: AppBar().preferredSize.height + 40, + height: AppBar().preferredSize.height, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Material( + color: Colors.transparent, + child: InkWell( + borderRadius: const BorderRadius.all( + Radius.circular(32.0), + ), + onTap: () {}, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Icon(Icons.favorite_border), + ), + ), + ), + Material( + color: Colors.transparent, + child: InkWell( + borderRadius: const BorderRadius.all( + Radius.circular(32.0), + ), + onTap: () {}, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Icon(FontAwesomeIcons.locationDot), + ), + ), + ), + ], + ), + ), + ], + ), + ), + ); + } +} + +class ContestTabHeader extends SliverPersistentHeaderDelegate { + ContestTabHeader( + this.searchUI, + ); + final Widget searchUI; + + @override + Widget build( + BuildContext context, double shrinkOffset, bool overlapsContent) { + return searchUI; + } + + @override + double get maxExtent => 52.0; + + @override + double get minExtent => 52.0; + + @override + bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) { + return false; + } +} diff --git a/lib/home__screen/leaderboard.dart b/lib/home__screen/leaderboard.dart new file mode 100644 index 0000000..5b09886 --- /dev/null +++ b/lib/home__screen/leaderboard.dart @@ -0,0 +1,384 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; + +void main() => runApp(MaterialApp(home: LeaderBoard())); + +const Color avtar_backGround = Color(0xFF2FCB72); +const Color avtar_backGround1 = Color(0xFF0C3329); +const Color prof_Card = Color(0xFF196F3D); +const Color grade1 = Color(0xFF00b09b); +const Color grade2 = Color(0xFF96c93d); +const Color cool = Color(0xFF181A2F); +const clickedColor = Color(0xFF0C3329); +const unclickedColor = Color(0xFF196F3D); +Color probtn = Color(0xFF0C3329); +Color leadbtn = Color(0xFF196F3D); +Color gold = Color(0xFFD0B13E); +Color silver = Color(0xFFE7E7E7); +Color bronze = Color(0xFFA45735); + +//Color list_item = Colors.grey[200]; + +class LeaderBoard extends StatefulWidget { + @override + State createState() => _LeaderBoardState(); +} + +class _LeaderBoardState extends State { + List names = [ + "1", + "2", + "3", + "4", + "1", + "2", + "3", + "4", + "1", + "2", + "3", + "4", + "1", + "2", + "3", + "4", + "1", + "2", + "3", + "4", + "1", + "2", + "3", + "4", + "1", + "2", + "3", + "4", + "1", + "2", + "3", + "4" + ]; + List litems = [ + "1", + "2", + "3", + "4", + "1", + "2", + "3", + "4", + "1", + "2", + "3", + "4", + "1", + "2", + "3", + "4", + "1", + "2", + "3", + "4", + "1", + "2", + "3", + "4", + "1", + "2", + "3", + "4", + "1", + "2", + "3", + "4" + ]; @override + Widget build(BuildContext context) { + + + return MaterialApp( + home: Scaffold( bottomNavigationBar: BottomAppBar( + child: Container( + color: cool, + child: Card( + margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0), + elevation: 0, + color: Colors.red, + child: Container( + padding: EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text("pos", + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + CircleAvatar( + foregroundColor: Colors.green, + ), + Text( + "name", + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold), + ), + Text( + "Score", + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold), + ) + ], + ), + ), + ), + ), + ), + + body: CustomScrollView( + slivers: [ + SliverAppBar( + backgroundColor: Color(0xFF408D4D), + pinned: true, + snap: false, + floating: false, + expandedHeight: 200.0, + bottom: PreferredSize( + preferredSize: Size.fromHeight(4.0), + child: Container( + color: Color(0xFF408D4D), + height: 50, + child: Container( + child: Row( + + children: [ + SizedBox(width: 35), + Text("Postion", + style: TextStyle( + color: Colors.grey[200], + fontWeight: FontWeight.bold)), + SizedBox(width: 52), + + Text( + "Profile", + style: + TextStyle( + color: Colors.grey[200], + fontWeight: FontWeight.bold), + ), + SizedBox(width: 60), + + Text( + "Name", + style: + TextStyle( + color: Colors.grey[200], + fontWeight: FontWeight.bold), + ), + SizedBox(width: 60), + + Text( + "Score", + style: TextStyle( + color: Colors.grey[200], + fontWeight: FontWeight.bold), + ) + ], + ),),),), + flexibleSpace: FlexibleSpaceBar( + background: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [Color(0xFF408D4D), cool])), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only(top: 50.0), + child: Text( + "LEADERBOARD", + style: TextStyle( + fontSize: 30, + color: Colors.grey[200], + fontWeight: FontWeight.bold), + ), + ), + SizedBox( + height: 20, + ), + Icon( + Icons.emoji_events_rounded, + color: gold, + size: 70, + ), + ], + ), + ), + ), + elevation: 9.0, + ), +SliverList( + delegate: SliverChildBuilderDelegate( + (BuildContext context,int index)=>buildList(context,index), + childCount: litems.length, +)) + ], + ), + ), + ); + + } + Widget buildList(BuildContext txt, int index) { + int ind = index + 1; + final pos = litems[index]; + final name = names[index]; + + Widget listItem; + + if (ind == 1) { + listItem = Card( + margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0), + shadowColor: Colors.grey[200], + color: gold, + child: Container( + padding: EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text(pos, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + CircleAvatar( + foregroundColor: Colors.green, + ), + Text( + name, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold), + ), + Text( + "Score", + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold), + ) + ], + ), + ), + ); + } else if (ind == 2) { + listItem = Card( + margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0), + shadowColor: Colors.grey[200], + color: silver, + child: Container( + padding: EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text(pos, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + CircleAvatar( + foregroundColor: Colors.green, + ), + Text( + name, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold), + ), + Text( + "Score", + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold), + ) + ], + ), + ), + ); + } else if (ind == 3) { + listItem = Card( + shadowColor: Colors.grey[200], + margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0), + color: Color(0xFF408D4D), + child: Container( + padding: EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text(pos, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + CircleAvatar( + foregroundColor: Colors.green, + ), + Text( + name, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold), + ), + Text( + "Score", + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold), + ) + ], + ), + ), + ); + } else { + listItem = Card( + margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0), + shadowColor: Colors.grey[200], + color: Colors.white, + child: Container( + padding: EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text(pos, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + CircleAvatar( + foregroundColor: Colors.green, + ), + Text( + name, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold), + ), + Text( + "Score", + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold), + ) + ], + ), + ), + ); + } + + return Stack( + children: [ + Container( + color: Colors.grey[200], + child: listItem, + ), + ], + ); + } + +} \ No newline at end of file diff --git a/lib/home__screen/model/home_list_data.dart b/lib/home__screen/model/home_list_data.dart new file mode 100644 index 0000000..1c4d516 --- /dev/null +++ b/lib/home__screen/model/home_list_data.dart @@ -0,0 +1,58 @@ +class HomeListData { + HomeListData({ + this.imagePath = '', + this.titleTxt = '', + this.subTxt = "", + this.dist = 1.8, + this.reviews = 80, + this.rating = 4.5, + this.perNight = "", + }); + + String imagePath; + String titleTxt; + String subTxt; + double dist; + double rating; + int reviews; + String perNight; + + static List homeList = [ + HomeListData( + imagePath: 'assets/images/yourwaifu.png', + titleTxt: 'AR Waifu', + subTxt: 'Try our AR Waifu now!', + dist: 2.0, + reviews: 80, + rating: 4.4, + // perNight: "Play", + ), + // HomeListData( + // imagePath: 'assets/homescreen/home_3.png', + // titleTxt: 'Planet Protectors', + // subTxt: 'Join the mission to save the planet and \nprotect its future.', + // dist: 3.0, + // reviews: 62, + // rating: 4.0, + // // perNight: "Play", + // ), + // HomeListData( + // imagePath: 'assets/homescreen/home_1.png', + // titleTxt: 'Eco Heroes', + // subTxt: 'Join the Eco Heroes and save the planet \nthrough sustainability', + // dist: 7.0, + // reviews: 90, + // rating: 4.4, + // // perNight: "Play", + // ), + // HomeListData( + // imagePath: 'assets/homescreen/home_2.png', + // titleTxt: 'Renewable Quest', + // subTxt: 'Save the kingdom with renewable energy', + // dist: 2.0, + // reviews: 240, + // rating: 4.5, + // // perNight: "Play", + // ), + ]; +} diff --git a/lib/home__screen/range_slider_view.dart b/lib/home__screen/range_slider_view.dart new file mode 100644 index 0000000..7133b3c --- /dev/null +++ b/lib/home__screen/range_slider_view.dart @@ -0,0 +1,194 @@ +import 'package:best_flutter_ui_templates/home__screen/home_app_theme.dart'; +import 'package:flutter/material.dart'; + +class RangeSliderView extends StatefulWidget { + const RangeSliderView({Key? key, this.values, this.onChangeRangeValues}) + : super(key: key); + + final Function(RangeValues)? onChangeRangeValues; + final RangeValues? values; + + @override + _RangeSliderViewState createState() => _RangeSliderViewState(); +} + +class _RangeSliderViewState extends State { + RangeValues? _values; + + @override + void initState() { + _values = widget.values; + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container( + child: Column( + children: [ + Stack( + children: [ + Row( + children: [ + Expanded( + flex: _values!.start.round(), + child: const SizedBox(), + ), + Container( + width: 54, + child: Text( + '\$${_values!.start.round()}', + textAlign: TextAlign.center, + ), + ), + Expanded( + flex: 1000 - _values!.start.round(), + child: const SizedBox(), + ), + ], + ), + Row( + children: [ + Expanded( + flex: _values!.end.round(), + child: const SizedBox(), + ), + Container( + width: 54, + child: Text( + '\$${_values!.end.round()}', + textAlign: TextAlign.center, + ), + ), + Expanded( + flex: 1000 - _values!.end.round(), + child: const SizedBox(), + ), + ], + ), + ], + ), + SliderTheme( + data: SliderThemeData( + rangeThumbShape: CustomRangeThumbShape(), + ), + child: RangeSlider( + values: _values!, + min: 0.0, + max: 1000.0, + activeColor: HomeAppTheme.buildLightTheme().primaryColor, + inactiveColor: Colors.grey.withOpacity(0.4), + divisions: 1000, + onChanged: (RangeValues values) { + try { + setState(() { + _values = values; + }); + widget.onChangeRangeValues!(_values!); + } catch (_) {} + }, + ), + ), + ], + ), + ); + } +} + +class CustomRangeThumbShape extends RangeSliderThumbShape { + static const double _thumbSize = 3.0; + static const double _disabledThumbSize = 3.0; + + @override + Size getPreferredSize(bool isEnabled, bool isDiscrete) { + return isEnabled + ? const Size.fromRadius(_thumbSize) + : const Size.fromRadius(_disabledThumbSize); + } + + static final Animatable sizeTween = Tween( + begin: _disabledThumbSize, + end: _thumbSize, + ); + + @override + void paint( + PaintingContext context, + Offset center, { + required Animation activationAnimation, + required Animation enableAnimation, + bool isDiscrete = false, + bool isEnabled = false, + bool? isOnTop, + bool? isPressed, + required SliderThemeData sliderTheme, + TextDirection textDirection = TextDirection.ltr, + Thumb thumb = Thumb.start, + }) { + final Canvas canvas = context.canvas; + final ColorTween colorTween = ColorTween( + begin: sliderTheme.disabledThumbColor, + end: sliderTheme.thumbColor, + ); + + final double size = _thumbSize * sizeTween.evaluate(enableAnimation); + Path thumbPath; + switch (textDirection) { + case TextDirection.rtl: + switch (thumb) { + case Thumb.start: + thumbPath = _rightTriangle(size, center); + break; + case Thumb.end: + thumbPath = _leftTriangle(size, center); + break; + } + break; + case TextDirection.ltr: + switch (thumb) { + case Thumb.start: + thumbPath = _leftTriangle(size, center); + break; + case Thumb.end: + thumbPath = _rightTriangle(size, center); + break; + } + break; + } + + canvas.drawPath( + Path() + ..addOval(Rect.fromPoints(Offset(center.dx + 12, center.dy + 12), + Offset(center.dx - 12, center.dy - 12))) + ..fillType = PathFillType.evenOdd, + Paint() + ..color = Colors.black.withOpacity(0.5) + ..maskFilter = + MaskFilter.blur(BlurStyle.normal, convertRadiusToSigma(8))); + + final Paint cPaint = Paint(); + cPaint..color = Colors.white; + cPaint..strokeWidth = 14 / 2; + canvas.drawCircle(Offset(center.dx, center.dy), 12, cPaint); + cPaint..color = colorTween.evaluate(enableAnimation)!; + canvas.drawCircle(Offset(center.dx, center.dy), 10, cPaint); + canvas.drawPath(thumbPath, Paint()..color = Colors.white); + } + + double convertRadiusToSigma(double radius) { + return radius * 0.57735 + 0.5; + } + + Path _rightTriangle(double size, Offset thumbCenter, {bool invert = false}) { + final Path thumbPath = Path(); + final double sign = invert ? -1.0 : 1.0; + thumbPath.moveTo(thumbCenter.dx + 5 * sign, thumbCenter.dy); + thumbPath.lineTo(thumbCenter.dx - 3 * sign, thumbCenter.dy - 5); + thumbPath.lineTo(thumbCenter.dx - 3 * sign, thumbCenter.dy + 5); + thumbPath.close(); + return thumbPath; + } + + Path _leftTriangle(double size, Offset thumbCenter) => + _rightTriangle(size, thumbCenter, invert: true); +} diff --git a/lib/home__screen/slider_view.dart b/lib/home__screen/slider_view.dart new file mode 100644 index 0000000..7d366c1 --- /dev/null +++ b/lib/home__screen/slider_view.dart @@ -0,0 +1,134 @@ +import 'package:best_flutter_ui_templates/home__screen/home_app_theme.dart'; +import 'package:flutter/material.dart'; + +class SliderView extends StatefulWidget { + const SliderView({Key? key, this.onChangedistValue, this.distValue}) + : super(key: key); + + final Function(double)? onChangedistValue; + final double? distValue; + + @override + _SliderViewState createState() => _SliderViewState(); +} + +class _SliderViewState extends State { + double distValue = 50.0; + + @override + void initState() { + distValue = widget.distValue!; + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container( + child: Column( + children: [ + Row( + children: [ + Expanded( + flex: distValue.round(), + child: const SizedBox(), + ), + Container( + width: 170, + child: Text( + 'Less than ${(distValue / 10).toStringAsFixed(1)} Km', + textAlign: TextAlign.center, + ), + ), + Expanded( + flex: 100 - distValue.round(), + child: const SizedBox(), + ), + ], + ), + SliderTheme( + data: SliderThemeData( + thumbShape: CustomThumbShape(), + ), + child: Slider( + onChanged: (double value) { + setState(() { + distValue = value; + }); + try { + widget.onChangedistValue!(distValue); + } catch (_) {} + }, + min: 0, + max: 100, + activeColor: HomeAppTheme.buildLightTheme().primaryColor, + inactiveColor: Colors.grey.withOpacity(0.4), + divisions: 100, + value: distValue, + ), + + ), + ], + ), + ); + } +} + +class CustomThumbShape extends SliderComponentShape { + static const double _thumbSize = 3.0; + static const double _disabledThumbSize = 3.0; + + @override + Size getPreferredSize(bool isEnabled, bool isDiscrete) { + return isEnabled + ? const Size.fromRadius(_thumbSize) + : const Size.fromRadius(_disabledThumbSize); + } + + static final Animatable sizeTween = Tween( + begin: _disabledThumbSize, + end: _thumbSize, + ); + + @override + void paint( + PaintingContext context, + Offset thumbCenter, { + Animation? activationAnimation, + Animation? enableAnimation, + bool? isDiscrete, + TextPainter? labelPainter, + RenderBox? parentBox, + Size? sizeWithOverflow, + SliderThemeData? sliderTheme, + TextDirection textDirection = TextDirection.ltr, + double? textScaleFactor, + double? value, + }) { + final Canvas canvas = context.canvas; + final ColorTween colorTween = ColorTween( + begin: sliderTheme?.disabledThumbColor, + end: sliderTheme?.thumbColor, + ); + canvas.drawPath( + Path() + ..addOval(Rect.fromPoints( + Offset(thumbCenter.dx + 12, thumbCenter.dy + 12), + Offset(thumbCenter.dx - 12, thumbCenter.dy - 12))) + ..fillType = PathFillType.evenOdd, + Paint() + ..color = Colors.black.withOpacity(0.5) + ..maskFilter = + MaskFilter.blur(BlurStyle.normal, convertRadiusToSigma(8))); + + final Paint cPaint = Paint(); + cPaint..color = Colors.white; + cPaint..strokeWidth = 14 / 2; + canvas.drawCircle(Offset(thumbCenter.dx, thumbCenter.dy), 12, cPaint); + cPaint..color = colorTween.evaluate(enableAnimation!)!; + canvas.drawCircle(Offset(thumbCenter.dx, thumbCenter.dy), 10, cPaint); + } + + double convertRadiusToSigma(double radius) { + return radius * 0.57735 + 0.5; + } +} diff --git a/lib/home_screen.dart b/lib/home_screen.dart new file mode 100644 index 0000000..1470f62 --- /dev/null +++ b/lib/home_screen.dart @@ -0,0 +1,233 @@ +import 'package:best_flutter_ui_templates/app_theme.dart'; +import 'package:flutter/material.dart'; +import 'model/homelist.dart'; + +class MyHomePage extends StatefulWidget { + const MyHomePage({Key? key}) : super(key: key); + + @override + _MyHomePageState createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State with TickerProviderStateMixin { + List homeList = HomeList.homeList; + AnimationController? animationController; + bool multiple = true; + + @override + void initState() { + animationController = AnimationController( + duration: const Duration(milliseconds: 2000), vsync: this); + super.initState(); + } + + Future getData() async { + await Future.delayed(const Duration(milliseconds: 0)); + return true; + } + + @override + void dispose() { + animationController?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + var brightness = MediaQuery.of(context).platformBrightness; + bool isLightMode = brightness == Brightness.light; + return Scaffold( + backgroundColor: + isLightMode == true ? AppTheme.white : AppTheme.nearlyBlack, + body: FutureBuilder( + future: getData(), + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (!snapshot.hasData) { + return const SizedBox(); + } else { + return Padding( + padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + appBar(), + Expanded( + child: FutureBuilder( + future: getData(), + builder: + (BuildContext context, AsyncSnapshot snapshot) { + if (!snapshot.hasData) { + return const SizedBox(); + } else { + return GridView( + padding: const EdgeInsets.only( + top: 0, left: 12, right: 12), + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.vertical, + children: List.generate( + homeList.length, + (int index) { + final int count = homeList.length; + final Animation animation = + Tween(begin: 0.0, end: 1.0).animate( + CurvedAnimation( + parent: animationController!, + curve: Interval((1 / count) * index, 1.0, + curve: Curves.fastOutSlowIn), + ), + ); + animationController?.forward(); + return HomeListView( + animation: animation, + animationController: animationController, + listData: homeList[index], + callBack: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => + homeList[index].navigateScreen!, + ), + ); + }, + ); + }, + ), + gridDelegate: + SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: multiple ? 2 : 1, + mainAxisSpacing: 12.0, + crossAxisSpacing: 12.0, + childAspectRatio: 1.5, + ), + ); + } + }, + ), + ), + ], + ), + ); + } + }, + ), + ); + } + + Widget appBar() { + var brightness = MediaQuery.of(context).platformBrightness; + bool isLightMode = brightness == Brightness.light; + return SizedBox( + height: AppBar().preferredSize.height, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8, left: 8), + child: Container( + width: AppBar().preferredSize.height - 8, + height: AppBar().preferredSize.height - 8, + ), + ), + Expanded( + child: Center( + child: Padding( + padding: const EdgeInsets.only(top: 4), + child: Text( + 'Flutter UI', + style: TextStyle( + fontSize: 22, + color: isLightMode ? AppTheme.darkText : AppTheme.white, + fontWeight: FontWeight.w700, + ), + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(top: 8, right: 8), + child: Container( + width: AppBar().preferredSize.height - 8, + height: AppBar().preferredSize.height - 8, + color: isLightMode ? Colors.white : AppTheme.nearlyBlack, + child: Material( + color: Colors.transparent, + child: InkWell( + borderRadius: + BorderRadius.circular(AppBar().preferredSize.height), + child: Icon( + multiple ? Icons.dashboard : Icons.view_agenda, + color: isLightMode ? AppTheme.dark_grey : AppTheme.white, + ), + onTap: () { + setState(() { + multiple = !multiple; + }); + }, + ), + ), + ), + ), + ], + ), + ); + } +} + +class HomeListView extends StatelessWidget { + const HomeListView( + {Key? key, + this.listData, + this.callBack, + this.animationController, + this.animation}) + : super(key: key); + + final HomeList? listData; + final VoidCallback? callBack; + final AnimationController? animationController; + final Animation? animation; + + @override + Widget build(BuildContext context) { + return AnimatedBuilder( + animation: animationController!, + builder: (BuildContext context, Widget? child) { + return FadeTransition( + opacity: animation!, + child: Transform( + transform: Matrix4.translationValues( + 0.0, 50 * (1.0 - animation!.value), 0.0), + child: AspectRatio( + aspectRatio: 1.5, + child: ClipRRect( + borderRadius: const BorderRadius.all(Radius.circular(4.0)), + child: Stack( + alignment: AlignmentDirectional.center, + children: [ + Positioned.fill( + child: Image.asset( + listData!.imagePath, + fit: BoxFit.cover, + ), + ), + Material( + color: Colors.transparent, + child: InkWell( + splashColor: Colors.grey.withOpacity(0.2), + borderRadius: + const BorderRadius.all(Radius.circular(4.0)), + onTap: callBack, + ), + ), + ], + ), + ), + ), + ), + ); + }, + ); + } +} diff --git a/lib/introduction_animation/components/care_view.dart b/lib/introduction_animation/components/care_view.dart new file mode 100644 index 0000000..6f8b425 --- /dev/null +++ b/lib/introduction_animation/components/care_view.dart @@ -0,0 +1,120 @@ +import 'package:flutter/material.dart'; + +class CareView extends StatelessWidget { + final AnimationController animationController; + + const CareView({Key? key, required this.animationController}) + : super(key: key); + + @override + Widget build(BuildContext context) { + final _firstHalfAnimation = + Tween(begin: Offset(1, 0), end: Offset(0, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.2, + 0.4, + curve: Curves.fastOutSlowIn, + ), + )); + final _secondHalfAnimation = + Tween(begin: Offset(0, 0), end: Offset(-1, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.4, + 0.6, + curve: Curves.fastOutSlowIn, + ), + )); + final _relaxFirstHalfAnimation = + Tween(begin: Offset(2, 0), end: Offset(0, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.2, + 0.4, + curve: Curves.fastOutSlowIn, + ), + )); + final _relaxSecondHalfAnimation = + Tween(begin: Offset(0, 0), end: Offset(-2, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.4, + 0.6, + curve: Curves.fastOutSlowIn, + ), + )); + + final _imageFirstHalfAnimation = + Tween(begin: Offset(4, 0), end: Offset(0, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.2, + 0.4, + curve: Curves.fastOutSlowIn, + ), + )); + final _imageSecondHalfAnimation = + Tween(begin: Offset(0, 0), end: Offset(-4, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.4, + 0.6, + curve: Curves.fastOutSlowIn, + ), + )); + + return SlideTransition( + position: _firstHalfAnimation, + child: SlideTransition( + position: _secondHalfAnimation, + child: Padding( + padding: const EdgeInsets.only(bottom: 100), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SlideTransition( + position: _imageFirstHalfAnimation, + child: SlideTransition( + position: _imageSecondHalfAnimation, + child: Container( + constraints: BoxConstraints(maxWidth: 350, maxHeight: 250), + child: Image.asset( + 'assets/introduction_animation/care_image.png', + fit: BoxFit.contain, + ), + ), + ), + ), + SlideTransition( + position: _relaxFirstHalfAnimation, + child: SlideTransition( + position: _relaxSecondHalfAnimation, + child: Text( + "Care", + style: TextStyle(fontSize: 54.0, fontWeight: FontWeight.w700, fontFamily: 'Inter', color: Color(0xFFffffff)), + ), + ), + ), + Padding( + padding: + EdgeInsets.only(left: 64, right: 64, bottom: 16, top: 16), + child: Text( + "Lorem ipsum dolor sit amet,consectetur adipiscing elit,sed do eiusmod tempor incididunt ut labore", + style: TextStyle(color: Color.fromARGB(182, 255, 255, 255),fontSize: 16, fontWeight: FontWeight.w600, fontFamily: 'Inter',), + textAlign: TextAlign.center, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/introduction_animation/components/center_next_button.dart b/lib/introduction_animation/components/center_next_button.dart new file mode 100644 index 0000000..62db554 --- /dev/null +++ b/lib/introduction_animation/components/center_next_button.dart @@ -0,0 +1,225 @@ +import 'package:animations/animations.dart'; +import 'package:best_flutter_ui_templates/login/pages/login_page.dart'; +import 'package:best_flutter_ui_templates/login/pages/signup_page.dart'; +import 'package:flutter/material.dart'; + +class CenterNextButton extends StatelessWidget { + final AnimationController animationController; + final VoidCallback onNextClick; + const CenterNextButton( + {Key? key, required this.animationController, required this.onNextClick}) + : super(key: key); + + @override + Widget build(BuildContext context) { + final _topMoveAnimation = + Tween(begin: Offset(0, 5), end: Offset(0, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.0, + 0.2, + curve: Curves.fastOutSlowIn, + ), + )); + final _signUpMoveAnimation = + Tween(begin: 0, end: 1.0).animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.6, + 0.8, + curve: Curves.fastOutSlowIn, + ), + )); + final _loginTextMoveAnimation = + Tween(begin: Offset(0, 5), end: Offset(0, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.6, + 0.8, + curve: Curves.fastOutSlowIn, + ), + )); + + return Padding( + padding: + EdgeInsets.only(bottom: 40 + MediaQuery.of(context).padding.bottom), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SlideTransition( + position: _topMoveAnimation, + child: AnimatedBuilder( + animation: animationController, + builder: (context, child) => AnimatedOpacity( + opacity: animationController.value >= 0.2 && + animationController.value <= 0.6 + ? 1 + : 0, + duration: Duration(milliseconds: 480), + child: _pageView(), + ), + ), + ), + SlideTransition( + position: _topMoveAnimation, + child: AnimatedBuilder( + animation: animationController, + builder: (context, child) => Padding( + padding: EdgeInsets.only( + bottom: 38 - (38 * _signUpMoveAnimation.value)), + child: Container( + height: 58, + width: 58 + (200 * _signUpMoveAnimation.value), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular( + 8 + 32 * (1 - _signUpMoveAnimation.value)), + color: Color(0xffffffff), + ), + child: PageTransitionSwitcher( + duration: Duration(milliseconds: 480), + reverse: _signUpMoveAnimation.value < 0.7, + transitionBuilder: ( + Widget child, + Animation animation, + Animation secondaryAnimation, + ) { + return SharedAxisTransition( + fillColor: Colors.transparent, + child: child, + animation: animation, + secondaryAnimation: secondaryAnimation, + transitionType: SharedAxisTransitionType.vertical, + ); + }, + child: _signUpMoveAnimation.value > 0.7 + ? GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SignupPage()), + ); + }, + child: InkWell( + key: ValueKey('Sign Up button'), + child: Padding( + padding: + EdgeInsets.only(left: 16.0, right: 16.0), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Sign Up', + style: TextStyle( + color: Color.fromRGBO(13, 44, 63, 1), + fontSize: 18, + fontFamily: 'Inter', + fontWeight: FontWeight.w600, + ), + ), + Icon(Icons.arrow_forward_rounded, + color: Color.fromRGBO(13, 44, 63, 1)), + ], + ), + ), + ), + ) + : InkWell( + key: ValueKey('next button'), + onTap: onNextClick, + child: Padding( + padding: EdgeInsets.all(16.0), + child: Icon(Icons.arrow_forward_ios_rounded, + color: Color.fromRGBO(13, 44, 63, 1)), + ), + ), + ), + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(top: 12), + child: SlideTransition( + position: _loginTextMoveAnimation, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Already have an account? ', + style: TextStyle( + color: Color.fromARGB(255, 248, 246, 246), + fontSize: 14, + fontWeight: FontWeight.w500, + fontFamily: 'Inter', + ), + ), + InkWell( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => LoginPage()), + ); + }, + child: Text( + 'Login', + style: TextStyle( + color: Color(0xFF0D2C3F), + fontSize: 14, + fontFamily: 'Inter', + fontWeight: FontWeight.w500, + decoration: TextDecoration.underline, + ), + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + Widget _pageView() { + int _selectedIndex = 0; + + if (animationController.value >= 0.7) { + _selectedIndex = 3; + } else if (animationController.value >= 0.5) { + _selectedIndex = 2; + } else if (animationController.value >= 0.3) { + _selectedIndex = 1; + } else if (animationController.value >= 0.1) { + _selectedIndex = 0; + } + + return Padding( + padding: const EdgeInsets.only(bottom: 16), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + for (var i = 0; i < 4; i++) + Padding( + padding: const EdgeInsets.all(4), + child: AnimatedContainer( + duration: Duration(milliseconds: 480), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(32), + color: _selectedIndex == i + ? Color(0xff0D2C3F) + : Color(0xffffffff), + ), + width: 10, + height: 10, + ), + ) + ], + ), + ); + } +} diff --git a/lib/introduction_animation/components/mood_diary_vew.dart b/lib/introduction_animation/components/mood_diary_vew.dart new file mode 100644 index 0000000..2773298 --- /dev/null +++ b/lib/introduction_animation/components/mood_diary_vew.dart @@ -0,0 +1,120 @@ +import 'package:flutter/material.dart'; + +class MoodDiaryVew extends StatelessWidget { + final AnimationController animationController; + + const MoodDiaryVew({Key? key, required this.animationController}) + : super(key: key); + + @override + Widget build(BuildContext context) { + final _firstHalfAnimation = + Tween(begin: Offset(1, 0), end: Offset(0, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.4, + 0.6, + curve: Curves.fastOutSlowIn, + ), + )); + final _secondHalfAnimation = + Tween(begin: Offset(0, 0), end: Offset(-1, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.6, + 0.8, + curve: Curves.fastOutSlowIn, + ), + )); + + final _moodFirstHalfAnimation = + Tween(begin: Offset(2, 0), end: Offset(0, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.4, + 0.6, + curve: Curves.fastOutSlowIn, + ), + )); + final _moodSecondHalfAnimation = + Tween(begin: Offset(0, 0), end: Offset(-2, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.6, + 0.8, + curve: Curves.fastOutSlowIn, + ), + )); + final _imageFirstHalfAnimation = + Tween(begin: Offset(4, 0), end: Offset(0, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.4, + 0.6, + curve: Curves.fastOutSlowIn, + ), + )); + final _imageSecondHalfAnimation = + Tween(begin: Offset(0, 0), end: Offset(-4, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.6, + 0.8, + curve: Curves.fastOutSlowIn, + ), + )); + + return SlideTransition( + position: _firstHalfAnimation, + child: SlideTransition( + position: _secondHalfAnimation, + child: Padding( + padding: const EdgeInsets.only(bottom: 100), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Mood Diary", + style: TextStyle(fontSize: 54.0, fontWeight: FontWeight.w700, fontFamily: 'Inter', color: Color(0xFFffffff)), + ), + SlideTransition( + position: _moodFirstHalfAnimation, + child: SlideTransition( + position: _moodSecondHalfAnimation, + child: Padding( + padding: EdgeInsets.only( + left: 64, right: 64, top: 16, bottom: 16), + child: Text( + "Lorem ipsum dolor sit amet,consectetur adipiscing elit,sed do eiusmod tempor incididunt ut labore", + style: TextStyle(color: Color.fromARGB(182, 255, 255, 255),fontSize: 16, fontWeight: FontWeight.w600, fontFamily: 'Inter',), + textAlign: TextAlign.center, + ), + ), + ), + ), + SlideTransition( + position: _imageFirstHalfAnimation, + child: SlideTransition( + position: _imageSecondHalfAnimation, + child: Container( + constraints: BoxConstraints(maxWidth: 350, maxHeight: 250), + child: Image.asset( + 'assets/introduction_animation/mood_diary_image.png', + fit: BoxFit.contain, + ), + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/introduction_animation/components/relax_view.dart b/lib/introduction_animation/components/relax_view.dart new file mode 100644 index 0000000..92908d9 --- /dev/null +++ b/lib/introduction_animation/components/relax_view.dart @@ -0,0 +1,111 @@ +import 'package:flutter/material.dart'; + +class RelaxView extends StatelessWidget { + final AnimationController animationController; + + const RelaxView({Key? key, required this.animationController}) + : super(key: key); + + @override + Widget build(BuildContext context) { + final _firstHalfAnimation = + Tween(begin: Offset(0, 1), end: Offset(0, 0)).animate( + CurvedAnimation( + parent: animationController, + curve: Interval( + 0.0, + 0.2, + curve: Curves.fastOutSlowIn, + ), + ), + ); + final _secondHalfAnimation = + Tween(begin: Offset(0, 0), end: Offset(-1, 0)).animate( + CurvedAnimation( + parent: animationController, + curve: Interval( + 0.2, + 0.4, + curve: Curves.fastOutSlowIn, + ), + ), + ); + final _textAnimation = + Tween(begin: Offset(0, 0), end: Offset(-2, 0)).animate( + CurvedAnimation( + parent: animationController, + curve: Interval( + 0.2, + 0.4, + curve: Curves.fastOutSlowIn, + ), + ), + ); + final _imageAnimation = + Tween(begin: Offset(0, 0), end: Offset(-4, 0)).animate( + CurvedAnimation( + parent: animationController, + curve: Interval( + 0.2, + 0.4, + curve: Curves.fastOutSlowIn, + ), + ), + ); + + final _relaxAnimation = + Tween(begin: Offset(0, -2), end: Offset(0, 0)).animate( + CurvedAnimation( + parent: animationController, + curve: Interval( + 0.0, + 0.2, + curve: Curves.fastOutSlowIn, + ), + ), + ); + return SlideTransition( + position: _firstHalfAnimation, + child: SlideTransition( + position: _secondHalfAnimation, + child: Padding( + padding: const EdgeInsets.only(bottom: 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SlideTransition( + position: _relaxAnimation, + child: Text( + "Relax", + style: TextStyle(fontSize: 54.0, fontWeight: FontWeight.w700, fontFamily: 'Inter', color: Color(0xFFffffff)), + ), + ), + SlideTransition( + position: _textAnimation, + child: Padding( + padding: + EdgeInsets.only(left: 40, right: 40, top: 16, bottom: 16), + child: Text( + "Lorem ipsum dolor sit amet,consectetur adipiscing elit,sed do eiusmod tempor incididunt ut labore Lorem ipsum dolor sit amet,consectetur adipiscing elit,sed do eiusmod", + style: TextStyle(color: Color.fromARGB(182, 255, 255, 255),fontSize: 16, fontWeight: FontWeight.w600, fontFamily: 'Inter',), + textAlign: TextAlign.center, + ), + ), + ), + SlideTransition( + position: _imageAnimation, + child: Container( + constraints: BoxConstraints(maxWidth: 350, maxHeight: 250), + child: Image.asset( + 'assets/introduction_animation/relax_image.png', + fit: BoxFit.contain, + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/introduction_animation/components/splash_view.dart b/lib/introduction_animation/components/splash_view.dart new file mode 100644 index 0000000..c3a457a --- /dev/null +++ b/lib/introduction_animation/components/splash_view.dart @@ -0,0 +1,96 @@ +import 'package:flutter/material.dart'; + +class SplashView extends StatefulWidget { + final AnimationController animationController; + + const SplashView({Key? key, required this.animationController}) + : super(key: key); + + @override + _SplashViewState createState() => _SplashViewState(); +} + +class _SplashViewState extends State { + @override + Widget build(BuildContext context) { + final _introductionanimation = + Tween(begin: Offset(0, 0), end: Offset(0.0, -1.0)) + .animate(CurvedAnimation( + parent: widget.animationController, + curve: Interval( + 0.0, + 0.2, + curve: Curves.fastOutSlowIn, + ), + )); + return SlideTransition( + position: _introductionanimation, + child: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + child: Container( + padding: const EdgeInsets.only(top: 140), + constraints: BoxConstraints(maxWidth: 350, maxHeight: 350), + child: Image.asset( + 'assets/introduction_animation/introduction_image.png', + fit: BoxFit.contain, + ), + ), + ), + Padding( + padding: EdgeInsets.only(top: 8.0, bottom: 8.0), + child: Text( + "Clearhead", + style: TextStyle(fontSize: 54.0, fontWeight: FontWeight.w700, fontFamily: 'Inter', color: Color(0xFFffffff)), + ), + ), + Padding( + padding: EdgeInsets.only(left: 64, right: 64), + child: Text( + "Lorem ipsum dolor sit amet,consectetur adipiscing elit,sed do eiusmod tempor incididunt ut labore", + style: TextStyle(color: Color.fromARGB(182, 255, 255, 255),fontSize: 16, fontWeight: FontWeight.w600, fontFamily: 'Inter',), + textAlign: TextAlign.center, + ), + ), + SizedBox( + height: 48, + ), + Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).padding.bottom + 16), + child: InkWell( + onTap: () { + widget.animationController.animateTo(0.2); + }, + child: Container( + height: 58, + padding: EdgeInsets.only( + left: 56.0, + right: 56.0, + top: 18, + bottom: 16, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(38.0), + color: Colors.white, + ), + child: Text( + "Let's begin", + style: TextStyle( + fontSize: 18, + fontFamily: 'Inter', + fontWeight: FontWeight.w500, + color: Color(0xff132137), + ), + ), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/introduction_animation/components/top_back_skip_view.dart b/lib/introduction_animation/components/top_back_skip_view.dart new file mode 100644 index 0000000..bcd437a --- /dev/null +++ b/lib/introduction_animation/components/top_back_skip_view.dart @@ -0,0 +1,91 @@ +import 'package:flutter/material.dart'; + +class TopBackSkipView extends StatelessWidget { + final AnimationController animationController; + final VoidCallback onBackClick; + final VoidCallback onSkipClick; + + const TopBackSkipView({ + Key? key, + required this.onBackClick, + required this.onSkipClick, + required this.animationController, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final _animation = + Tween(begin: Offset(0, -1), end: Offset(0.0, 0.0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.0, + 0.2, + curve: Curves.fastOutSlowIn, + ), + )); + + // final _backAnimation = + // Tween(begin: Offset(0, 0), end: Offset(-2, 0)) + // .animate(CurvedAnimation( + // parent: animationController, + // curve: Interval( + // 0.6, + // 0.8, + // curve: Curves.fastOutSlowIn, + // ), + // )); + final _skipAnimation = Tween(begin: Offset(0, 0), end: Offset(2, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.6, + 0.8, + curve: Curves.fastOutSlowIn, + ), + )); + + return SlideTransition( + position: _animation, + child: Padding( + padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top), + child: Container( + height: 60, + child: Padding( + padding: const EdgeInsets.only(left: 8, right: 16, top: 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // SlideTransition( + // position: _backAnimation, + // child: + IconButton( + onPressed: onBackClick, + icon: Icon( + Icons.arrow_back_ios_new_rounded, + color: Color(0xFFffffff), // set the color of the icon + ), + ), + + SlideTransition( + position: _skipAnimation, + child: IconButton( + onPressed: onSkipClick, + icon: Container( + child: Text('Skip', + style: TextStyle( + color: Color.fromARGB(218, 255, 255, 255), + fontSize: 20.0, + fontWeight: FontWeight.w400, + fontFamily: 'Inter')), + ), + ), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/introduction_animation/components/welcome_view.dart b/lib/introduction_animation/components/welcome_view.dart new file mode 100644 index 0000000..eeaf6cf --- /dev/null +++ b/lib/introduction_animation/components/welcome_view.dart @@ -0,0 +1,96 @@ +import 'package:flutter/material.dart'; + +class WelcomeView extends StatelessWidget { + final AnimationController animationController; + const WelcomeView({Key? key, required this.animationController}) + : super(key: key); + + @override + Widget build(BuildContext context) { + final _firstHalfAnimation = + Tween(begin: Offset(1, 0), end: Offset(0, 0)).animate( + CurvedAnimation( + parent: animationController, + curve: Interval( + 0.6, + 0.8, + curve: Curves.fastOutSlowIn, + ), + ), + ); + final _secondHalfAnimation = + Tween(begin: Offset(0, 0), end: Offset(-1, 0)).animate( + CurvedAnimation( + parent: animationController, + curve: Interval( + 0.8, + 1.0, + curve: Curves.fastOutSlowIn, + ), + ), + ); + + final _welcomeFirstHalfAnimation = + Tween(begin: Offset(2, 0), end: Offset(0, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.6, + 0.8, + curve: Curves.fastOutSlowIn, + ), + )); + + final _welcomeImageAnimation = + Tween(begin: Offset(4, 0), end: Offset(0, 0)) + .animate(CurvedAnimation( + parent: animationController, + curve: Interval( + 0.6, + 0.8, + curve: Curves.fastOutSlowIn, + ), + )); + return SlideTransition( + position: _firstHalfAnimation, + child: SlideTransition( + position: _secondHalfAnimation, + child: Padding( + padding: const EdgeInsets.only(bottom: 100), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SlideTransition( + position: _welcomeImageAnimation, + child: + Container( + constraints: BoxConstraints(maxWidth: 350, maxHeight: 350), + child: Image.asset( + 'assets/introduction_animation/welcome_image.png', + fit: BoxFit.contain, + ), + ), + ), + SlideTransition( + position: _welcomeFirstHalfAnimation, + child: Text( + "Welcome", + style: TextStyle(fontSize: 54.0, fontWeight: FontWeight.w700, fontFamily: 'Inter', color: Color(0xFFffffff)), + ), + ), + Padding( + padding: + EdgeInsets.only(left: 64, right: 64, top: 16, bottom: 16), + child: Text( + "Stay organised and live stress-free with you-do app", + style: TextStyle(color: Color.fromARGB(182, 255, 255, 255),fontSize: 16, fontWeight: FontWeight.w600, fontFamily: 'Inter',), + textAlign: TextAlign.center, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/introduction_animation/introduction_animation_screen.dart b/lib/introduction_animation/introduction_animation_screen.dart new file mode 100644 index 0000000..e390465 --- /dev/null +++ b/lib/introduction_animation/introduction_animation_screen.dart @@ -0,0 +1,117 @@ +import 'package:best_flutter_ui_templates/introduction_animation/components/care_view.dart'; +import 'package:best_flutter_ui_templates/introduction_animation/components/center_next_button.dart'; +import 'package:best_flutter_ui_templates/introduction_animation/components/mood_diary_vew.dart'; +import 'package:best_flutter_ui_templates/introduction_animation/components/relax_view.dart'; +import 'package:best_flutter_ui_templates/introduction_animation/components/splash_view.dart'; +import 'package:best_flutter_ui_templates/introduction_animation/components/top_back_skip_view.dart'; +import 'package:best_flutter_ui_templates/introduction_animation/components/welcome_view.dart'; +import 'package:flutter/material.dart'; + +class IntroductionAnimationScreen extends StatefulWidget { + const IntroductionAnimationScreen({Key? key}) : super(key: key); + + @override + _IntroductionAnimationScreenState createState() => + _IntroductionAnimationScreenState(); +} + +class _IntroductionAnimationScreenState + extends State with TickerProviderStateMixin { + AnimationController? _animationController; + + @override + void initState() { + _animationController = + AnimationController(vsync: this, duration: Duration(seconds: 8)); + _animationController?.animateTo(0.0); + super.initState(); + } + + @override + void dispose() { + _animationController?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + print(_animationController?.value); + return Scaffold( + backgroundColor: Color(0xFF408D4D), + body: ClipRect( + child: Stack( + children: [ + SplashView( + animationController: _animationController!, + ), + RelaxView( + animationController: _animationController!, + ), + CareView( + animationController: _animationController!, + ), + MoodDiaryVew( + animationController: _animationController!, + ), + WelcomeView( + animationController: _animationController!, + ), + TopBackSkipView( + onBackClick: _onBackClick, + onSkipClick: _onSkipClick, + animationController: _animationController!, + ), + CenterNextButton( + animationController: _animationController!, + onNextClick: _onNextClick, + ), + ], + ), + ), + ); + } + + void _onSkipClick() { + _animationController?.animateTo(0.8, + duration: Duration(milliseconds: 1200)); + } + + void _onBackClick() { + if (_animationController!.value >= 0 && + _animationController!.value <= 0.2) { + _animationController?.animateTo(0.0); + } else if (_animationController!.value > 0.2 && + _animationController!.value <= 0.4) { + _animationController?.animateTo(0.2); + } else if (_animationController!.value > 0.4 && + _animationController!.value <= 0.6) { + _animationController?.animateTo(0.4); + } else if (_animationController!.value > 0.6 && + _animationController!.value <= 0.8) { + _animationController?.animateTo(0.6); + } else if (_animationController!.value > 0.8 && + _animationController!.value <= 1.0) { + _animationController?.animateTo(0.8); + } + } + + void _onNextClick() { + if (_animationController!.value >= 0 && + _animationController!.value <= 0.2) { + _animationController?.animateTo(0.4); + } else if (_animationController!.value > 0.2 && + _animationController!.value <= 0.4) { + _animationController?.animateTo(0.6); + } else if (_animationController!.value > 0.4 && + _animationController!.value <= 0.6) { + _animationController?.animateTo(0.8); + } else if (_animationController!.value > 0.6 && + _animationController!.value <= 0.8) { + _signUpClick(); + } + } + + void _signUpClick() { + Navigator.pop(context); + } +} diff --git a/lib/invite_friend_screen.dart b/lib/invite_friend_screen.dart new file mode 100644 index 0000000..9af74f3 --- /dev/null +++ b/lib/invite_friend_screen.dart @@ -0,0 +1,55 @@ +import 'package:best_flutter_ui_templates/app_theme.dart'; +import 'package:flutter/material.dart'; + +class InviteFriend extends StatefulWidget { + @override + _InviteFriendState createState() => _InviteFriendState(); +} + +class _InviteFriendState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + var brightness = MediaQuery.of(context).platformBrightness; + bool isLightMode = brightness == Brightness.light; + return Container( + color: isLightMode ? AppTheme.white : AppTheme.nearlyBlack, + child: SafeArea( + top: false, + child: Scaffold( + backgroundColor: isLightMode ? AppTheme.white : AppTheme.nearlyBlack, + body: Column( + children: [ + Container( + child: Image.asset( + 'assets/images/group.png'), // change image crop needed + ), + Container( + padding: EdgeInsets.only( + top: MediaQuery.of(context).padding.top, + left: 16, + right: 16), + child: Image.asset('assets/images/group.jpg'), + ), + Container( + padding: const EdgeInsets.only(top: 16), + child: Text( + 'We are a group formed during the Flutter Bootcamp organized by GDSC APU & UM. Yeo Yee Tao (1st from left) from Johor, Malaysia, is a 2nd year Computer Science student in specialism of Data Analytics in Asia Pacific University of Technology & Innovation. Sattish Pratap Shewkani (2nd from left) from Bandung, Indonesia, is a 2nd year Computer Science student in specialism of Data Analytics in Asia Pacific University of Technology & Innovation. Quah Seng Kit (3rd from left) from Kuala Lumpur, Malaysia, is a 2nd year Computer Science student in specialism of Data Analytics in Asia Pacific University of Technology & Innovation. Lastly, Elias Yap (most right side) is a Postgraduate student in Business Administration from University of Malaya.', + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 16, + color: isLightMode ? Colors.black : Colors.white, + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/login/components/my_textfield.dart b/lib/login/components/my_textfield.dart new file mode 100644 index 0000000..3b08112 --- /dev/null +++ b/lib/login/components/my_textfield.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; + +class MyTextField extends StatelessWidget { + final controller; + final String hintText; + final bool obscureText; + + const MyTextField({ + super.key, + required this.controller, + required this.hintText, + required this.obscureText, + }); + +@override +Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 25.0), + child: TextField( + controller: controller, + obscureText: obscureText, + decoration: InputDecoration( + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.white), + borderRadius: BorderRadius.circular(10.0), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.black), + borderRadius: BorderRadius.circular(10.0), + ), + fillColor: Colors.grey.shade200, + filled: true, + hintText: hintText, + hintStyle: TextStyle(color: Colors.grey[500]), + contentPadding: EdgeInsets.symmetric(vertical: 16.0, horizontal: 10.0), + ), + ), + ); +} + +} \ No newline at end of file diff --git a/lib/login/components/signin_button.dart b/lib/login/components/signin_button.dart new file mode 100644 index 0000000..2306212 --- /dev/null +++ b/lib/login/components/signin_button.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; + +class SigninButton extends StatelessWidget { + final Function()? onTap; + + const SigninButton({Key? key, required this.onTap}) : super(key: key); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + padding: const EdgeInsets.all(18), + margin: const EdgeInsets.symmetric(horizontal: 25), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: const Center( + child: Text( + "Sign In", + style: TextStyle( + color: Color(0xff408D4D), + fontWeight: FontWeight.bold, + fontSize: 18, + fontFamily: 'Inter', + ), + ), + ), + ), + ); + } +} diff --git a/lib/login/components/signup_button.dart b/lib/login/components/signup_button.dart new file mode 100644 index 0000000..6e4da13 --- /dev/null +++ b/lib/login/components/signup_button.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; + +class SignupButton extends StatelessWidget { + final Function()? onTap; + + const SignupButton({super.key, required this.onTap}); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + padding: const EdgeInsets.all(18), + margin: const EdgeInsets.symmetric(horizontal: 25), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: const Center( + child: Text( + "Sign Up", + style: TextStyle( + color: Color(0xff408D4D), + fontWeight: FontWeight.bold, + fontSize: 18, + fontFamily: 'Inter', + ), + ), + ), + ), + ); + } +} diff --git a/lib/login/components/square_tile.dart b/lib/login/components/square_tile.dart new file mode 100644 index 0000000..5635707 --- /dev/null +++ b/lib/login/components/square_tile.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; + +class SquareTile extends StatelessWidget { + final String imagePath; + final Function()? onTap; + const SquareTile({ + super.key, + required this.imagePath, + required this.onTap, + }); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + padding: EdgeInsets.all(18), + decoration: BoxDecoration( + border: Border.all(color: Colors.white), + borderRadius: BorderRadius.circular(16), + color: Colors.grey[200], + ), + child: Image.asset( + imagePath, + height: 40, + ), + ), + ); + } +} diff --git a/lib/login/main_page.dart b/lib/login/main_page.dart new file mode 100644 index 0000000..0b225a6 --- /dev/null +++ b/lib/login/main_page.dart @@ -0,0 +1,24 @@ +import 'package:best_flutter_ui_templates/login/pages/auth_page.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/material.dart'; +import '../firebase_options.dart'; + +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + runApp(const LoginApp()); +} + +class LoginApp extends StatelessWidget { + const LoginApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: AuthPage(), + ); + } +} \ No newline at end of file diff --git a/lib/login/pages/auth_page.dart b/lib/login/pages/auth_page.dart new file mode 100644 index 0000000..474876a --- /dev/null +++ b/lib/login/pages/auth_page.dart @@ -0,0 +1,28 @@ +import 'package:best_flutter_ui_templates/introduction_animation/introduction_animation_screen.dart'; +import 'package:best_flutter_ui_templates/login/pages/signup_page.dart'; +import 'package:best_flutter_ui_templates/navigation_home_screen.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; + +class AuthPage extends StatelessWidget { + const AuthPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: StreamBuilder( + stream: FirebaseAuth.instance.authStateChanges(), + builder: (context, snapshot) { + //user is logged in + if (snapshot.hasData) { + return NavigationHomeScreen(); + } + //user is NOT logged in + else { + return IntroductionAnimationScreen(); + } + }, + ), + ); + } +} diff --git a/lib/login/pages/login_page.dart b/lib/login/pages/login_page.dart new file mode 100644 index 0000000..4993b5b --- /dev/null +++ b/lib/login/pages/login_page.dart @@ -0,0 +1,249 @@ +import 'package:best_flutter_ui_templates/home__screen/home_screen_secodary.dart'; +import 'package:best_flutter_ui_templates/login/pages/signup_page.dart'; +import 'package:best_flutter_ui_templates/login/services/auth_service.dart'; +import 'package:best_flutter_ui_templates/navigation_home_screen.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:best_flutter_ui_templates/login/components/signin_button.dart'; +import 'package:best_flutter_ui_templates/login/components/my_textfield.dart'; +import 'package:best_flutter_ui_templates/login/components/square_tile.dart'; + +class LoginPage extends StatefulWidget { + LoginPage({super.key}); + + @override + State createState() => _LoginPageState(); +} + +class _LoginPageState extends State { + // text editing controllers + final emailController = TextEditingController(); + + final passwordController = TextEditingController(); + + void showErrorMessage(String message) { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + backgroundColor: Colors.deepPurple, + title: Center( + child: Text( + message, + style: const TextStyle(color: Colors.white), + ), + )); + }, + ); + } + + // sign user in method + void signUserIn(BuildContext context) async { + showDialog( + context: context, + builder: (context) { + return const Center( + child: CircularProgressIndicator(), + ); + }, + ); + + try { + print('signUserIn function called'); + await FirebaseAuth.instance.signInWithEmailAndPassword( + email: emailController.text, + password: passwordController.text, + ); + print('User signed in successfully'); + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (BuildContext context) => HomeScreen()), + ); + } on FirebaseAuthException catch (e) { + Navigator.pop(context); // Close the dialog + showErrorMessage(e.code); + } + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: Scaffold( + backgroundColor: const Color(0xff408D4D), + appBar: AppBar( + leading: IconButton( + icon: Icon(Icons.arrow_back_ios_new_rounded), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SignupPage(), + ), + ); + }, + ), + backgroundColor: Colors.transparent, + elevation: 0, + ), + body: SafeArea( + child: SingleChildScrollView( + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const SizedBox( + height: 30, + ), + // logo + SizedBox( + height: 200, + width: 350, + child: Image.asset('assets/images/login_image.png'), + ), + const SizedBox( + height: 50, + ), + // welcome back, you've been missed! + const Text( + 'Welcome back you\'ve been missed!', + style: TextStyle( + color: Colors.white, fontSize: 16, fontFamily: 'Inter'), + ), + const SizedBox( + height: 25, + ), + // username textfield + MyTextField( + controller: emailController, + hintText: 'Email', + obscureText: false, + ), + const SizedBox( + height: 10, + ), + // password textfield + MyTextField( + controller: passwordController, + hintText: 'Password', + obscureText: true, + ), + const SizedBox( + height: 14, + ), + // forgot password? + Padding( + padding: const EdgeInsets.symmetric(horizontal: 25.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: const [ + Text( + 'Forgot Password?', + style: TextStyle( + color: Colors.white, fontFamily: 'Inter'), + ), + ], + ), + ), + const SizedBox( + height: 25, + ), + // sign in button + SigninButton( + onTap: () => signUserIn(context), + ), + + const SizedBox( + height: 50, + ), + // or continue with + Padding( + padding: const EdgeInsets.symmetric(horizontal: 25.0), + child: Row( + children: const [ + Expanded( + child: Divider( + thickness: 0.5, + color: Colors.white, + ), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 10.0), + child: Text( + 'Or continue with', + style: TextStyle( + color: Colors.white, + fontFamily: 'Inter', + ), + ), + ), + Expanded( + child: Divider( + thickness: 0.5, + color: Colors.white, + ), + ), + ], + ), + ), + const SizedBox( + height: 30, + ), + // google + apple sign in buttons + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // google button + SquareTile( + onTap: () => AuthService().signInWithGoogle(context), + imagePath: 'assets/images/google.png'), + SizedBox(width: 25), + // apple button + SquareTile( + onTap: () {}, + imagePath: 'assets/images/apple.png') + ], + ), + const SizedBox( + height: 30, + ), + // not a member? register now + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Not a member?', + style: + TextStyle(color: Colors.white, fontFamily: 'Inter'), + ), + SizedBox( + width: 4, + ), + InkWell( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SignupPage()), + ); + }, + child: Text( + 'Register Now', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontFamily: 'Inter'), + ), + ), + ], + ) + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/login/pages/signup_page.dart b/lib/login/pages/signup_page.dart new file mode 100644 index 0000000..4bf4b9d --- /dev/null +++ b/lib/login/pages/signup_page.dart @@ -0,0 +1,268 @@ +import 'package:best_flutter_ui_templates/login/services/auth_service.dart'; +import 'package:best_flutter_ui_templates/navigation_home_screen.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:best_flutter_ui_templates/login/components/signup_button.dart'; +import 'package:best_flutter_ui_templates/login/pages/login_page.dart'; +import 'package:best_flutter_ui_templates/login/components/my_textfield.dart'; +import 'package:best_flutter_ui_templates/login/components/square_tile.dart'; +import '../../introduction_animation/introduction_animation_screen.dart'; + +class SignupPage extends StatelessWidget { + SignupPage({super.key}); + + // text editing controllers + final nameController = TextEditingController(); + final emailController = TextEditingController(); + final passwordController = TextEditingController(); + final confirmPasswordController = TextEditingController(); + + // sign user in method + dynamic signUserUp(BuildContext context) async { + showDialog( + context: context, + builder: (context) { + return const Center( + child: CircularProgressIndicator(), + ); + }, + ); + + void showErrorMessage(String message) { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + backgroundColor: Colors.deepPurple, + title: Center( + child: Text( + message, + style: const TextStyle(color: Colors.white), + ), + )); + }, + ); + } + + if (passwordController.text != confirmPasswordController.text) { + Navigator.pop(context); + showErrorMessage("Passwords do not match"); + return; + } + + try { + print('signUserUp function called'); + await FirebaseAuth.instance.createUserWithEmailAndPassword( + email: emailController.text, + password: passwordController.text, + ); + print('User signed up successfully'); + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (BuildContext context) => NavigationHomeScreen()), + ); + } on FirebaseAuthException catch (e) { + Navigator.pop(context); // Close the dialog + showErrorMessage(e.code); + } + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: Scaffold( + backgroundColor: const Color(0xff408D4D), + appBar: AppBar( + leading: IconButton( + icon: Icon(Icons.arrow_back_ios_new_rounded), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => IntroductionAnimationScreen(), + ), + ); + }, + ), + backgroundColor: Colors.transparent, + elevation: 0, + ), + body: SafeArea( + child: SingleChildScrollView( + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const SizedBox( + height: 26, + ), + // logo + SizedBox( + height: 200, + width: 350, + child: Image.asset('assets/images/signup_image.png'), + ), + const SizedBox( + height: 10, + ), + // welcome back, you've been missed! + const Text( + 'Let\'s Create An Account For You!', + style: TextStyle( + color: Colors.white, fontSize: 16, fontFamily: 'Inter'), + ), + const SizedBox( + height: 20, //12 + ), + // username textfield + // MyTextField( + // controller: nameController, + // hintText: 'Name', + // obscureText: false, + // ), + // const SizedBox( + // height: 10, + // ), + // password textfield + MyTextField( + controller: emailController, + hintText: 'Email', + obscureText: false, + ), + const SizedBox( + height: 14, + ), + MyTextField( + controller: passwordController, + hintText: 'Password', + obscureText: true, + ), + const SizedBox( + height: 10, + ), + // password textfield + MyTextField( + controller: confirmPasswordController, + hintText: 'Confirm Password', + obscureText: true, + ), + const SizedBox( + height: 24, //14 + ), + // forgot password? + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 25.0), + // child: Row( + // mainAxisAlignment: MainAxisAlignment.end, + // children: const [ + // // Text( + // // 'Forgot Password?', + // // style: TextStyle(color: Colors.white), + // // ), + // ], + // ), + // ), + const SizedBox( + height: 4, + ), + // sign in button + SignupButton( + onTap: () { + signUserUp(context); + }, + ), + const SizedBox( + height: 30, //20 + ), + // or continue with + Padding( + padding: const EdgeInsets.symmetric(horizontal: 25.0), + child: Row( + children: const [ + Expanded( + child: Divider( + thickness: 0.5, + color: Colors.white, + ), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 10.0), + child: Text( + 'Or continue with', + style: TextStyle( + color: Colors.white, fontFamily: 'Inter'), + ), + ), + Expanded( + child: Divider( + thickness: 0.5, + color: Colors.white, + ), + ), + ], + ), + ), + const SizedBox( + height: 30, + ), + // google + apple sign in buttons + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // google button + SquareTile( + onTap: () => AuthService().signInWithGoogle(context), + imagePath: 'assets/images/google.png'), + SizedBox(width: 25), + // apple button + SquareTile( + onTap: () { + + }, + imagePath: 'assets/images/apple.png') + ], + ), + const SizedBox( + height: 20, + ), + // not a member? register now + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Already a member?', + style: + TextStyle(color: Colors.white, fontFamily: 'Inter'), + ), + SizedBox( + width: 4, + ), + InkWell( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => LoginPage()), + ); + }, + child: Text( + 'Login', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontFamily: 'Inter'), + ), + ), + ], + ) + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/login/services/auth_service.dart b/lib/login/services/auth_service.dart new file mode 100644 index 0000000..08aa797 --- /dev/null +++ b/lib/login/services/auth_service.dart @@ -0,0 +1,56 @@ +import 'package:best_flutter_ui_templates/navigation_home_screen.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:google_sign_in/google_sign_in.dart'; + + +class AuthService { + signOutWithGoogle() async { + if (await GoogleSignIn().isSignedIn()) { + GoogleSignIn().signOut(); + } + } + Future signInWithGoogle(BuildContext context) async { + final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn(); + + if (googleUser != null) { + final GoogleSignInAuthentication googleAuth = + await googleUser.authentication; + + final credential = GoogleAuthProvider.credential( + accessToken: googleAuth.accessToken, + idToken: googleAuth.idToken, + ); + + try { + final UserCredential userCredential = + await FirebaseAuth.instance.signInWithCredential(credential); + + final User? user = userCredential.user; + + if (user != null) { + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (context) => NavigationHomeScreen(), + ), + ); + + return user; + } + } on FirebaseAuthException catch (e) { + if (e.code == 'account-exists-with-different-credential') { + // handle the error here + } else if (e.code == 'invalid-credential') { + // handle the error here + } + } catch (e) { + // handle the error here + } + } + + return null; + + } + +} diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 0000000..fd7c991 --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,57 @@ +import 'dart:io'; +import 'package:best_flutter_ui_templates/app_theme.dart'; +import 'package:best_flutter_ui_templates/login/pages/auth_page.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'navigation_home_screen.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'firebase_options.dart'; +import 'package:flutter/foundation.dart' show kIsWeb; + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + await SystemChrome.setPreferredOrientations([ + DeviceOrientation.portraitUp, + DeviceOrientation.portraitDown + ]).then((_) => runApp(MyApp())); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + statusBarIconBrightness: Brightness.dark, + statusBarBrightness: + !kIsWeb && Platform.isAndroid ? Brightness.dark : Brightness.light, + systemNavigationBarColor: Colors.white, + systemNavigationBarDividerColor: Colors.transparent, + systemNavigationBarIconBrightness: Brightness.dark, + )); + return MaterialApp( + title: 'Flutter UI', + debugShowCheckedModeBanner: false, + theme: ThemeData( + primarySwatch: Colors.blue, + textTheme: AppTheme.textTheme, + platform: TargetPlatform.iOS, + ), + home: AuthPage(), + ); + } +} + +class HexColor extends Color { + HexColor(final String hexColor) : super(_getColorFromHex(hexColor)); + + static int _getColorFromHex(String hexColor) { + hexColor = hexColor.toUpperCase().replaceAll('#', ''); + if (hexColor.length == 6) { + hexColor = 'FF' + hexColor; + } + return int.parse(hexColor, radix: 16); + } +} diff --git a/lib/model/homelist.dart b/lib/model/homelist.dart new file mode 100644 index 0000000..fe0b7c2 --- /dev/null +++ b/lib/model/homelist.dart @@ -0,0 +1,39 @@ +import 'package:best_flutter_ui_templates/arcore_app/arcore_screen.dart'; +import 'package:best_flutter_ui_templates/home__screen/home_screen_secodary.dart'; +import 'package:best_flutter_ui_templates/introduction_animation/introduction_animation_screen.dart'; +import 'package:best_flutter_ui_templates/login/pages/login_page.dart'; +import 'package:best_flutter_ui_templates/login/pages/signup_page.dart'; +import 'package:flutter/widgets.dart'; + +class HomeList { + HomeList({ + this.navigateScreen, + this.imagePath = '', + }); + + Widget? navigateScreen; + String imagePath; + + static List homeList = [ + HomeList( + imagePath: 'assets/introduction_animation/introduction_animation.png', + navigateScreen: IntroductionAnimationScreen(), + ), + HomeList( + imagePath: 'assets/hotel/hotel_booking.png', + navigateScreen: HomeScreen(), + ), + HomeList( + imagePath: 'assets/design_course/login_page_image.png', + navigateScreen: LoginPage(), + ), + HomeList( + imagePath: 'assets/design_course/signup_page_image.png', + navigateScreen: SignupPage(), + ), + HomeList( + imagePath: 'assets/design_course/design_course.png', + navigateScreen: ArCoreApp(), + ), + ]; +} diff --git a/lib/navigation_home_screen.dart b/lib/navigation_home_screen.dart new file mode 100644 index 0000000..cfc3114 --- /dev/null +++ b/lib/navigation_home_screen.dart @@ -0,0 +1,80 @@ +import 'package:best_flutter_ui_templates/app_theme.dart'; +import 'package:best_flutter_ui_templates/custom_drawer/drawer_user_controller.dart'; +import 'package:best_flutter_ui_templates/custom_drawer/home_drawer.dart'; +import 'package:best_flutter_ui_templates/feedback_screen.dart'; +import 'package:best_flutter_ui_templates/help_screen.dart'; +import 'package:best_flutter_ui_templates/home_screen.dart'; +import 'package:best_flutter_ui_templates/home__screen/home_screen_secodary.dart'; +import 'package:best_flutter_ui_templates/invite_friend_screen.dart'; +import 'package:flutter/material.dart'; + +class NavigationHomeScreen extends StatefulWidget { + @override + _NavigationHomeScreenState createState() => _NavigationHomeScreenState(); +} + +class _NavigationHomeScreenState extends State { + Widget? screenView; + DrawerIndex? drawerIndex; + + @override + void initState() { + drawerIndex = DrawerIndex.HOME; + screenView = HomeScreen(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container( + color: AppTheme.white, + child: SafeArea( + top: false, + bottom: false, + child: Scaffold( + backgroundColor: AppTheme.nearlyWhite, + body: DrawerUserController( + screenIndex: drawerIndex, + drawerWidth: MediaQuery.of(context).size.width * 0.75, + onDrawerCall: (DrawerIndex drawerIndexdata) { + changeIndex(drawerIndexdata); + //callback from drawer for replace screen as user need with passing DrawerIndex(Enum index) + }, + screenView: screenView, + //we replace screen view as we need on navigate starting screens like MyHomePage, HelpScreen, FeedbackScreen, etc... + ), + ), + ), + ); + } + + void changeIndex(DrawerIndex drawerIndexdata) { + if (drawerIndex != drawerIndexdata) { + drawerIndex = drawerIndexdata; + switch (drawerIndex) { + case DrawerIndex.HOME: + setState(() { + screenView = HomeScreen(); //hotel_Screen CHANGE + }); + break; + case DrawerIndex.Help: + setState(() { + screenView = HelpScreen(); + }); + break; + case DrawerIndex.FeedBack: + setState(() { + screenView = FeedbackScreen(); + }); + break; + case DrawerIndex.Invite: + setState(() { + screenView = InviteFriend(); + }); + break; + default: + break; + } + } + } +} diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..88cda20 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,118 @@ +name: best_flutter_ui_templates +description: A new Flutter project. + +# The following line prevents the package from being accidentally published to +# pub.dev using `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 used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.17.5 <3.0.0" + +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.2 + arcore_flutter_plugin: + font_awesome_flutter: ^10.1.0 + flutter_rating_bar: ^4.0.1 + intl: ^0.17.0 + animations: ^2.0.3 + firebase_core: ^2.8.0 + firebase_auth: ^4.3.0 + google_sign_in: ^6.0.2 + model_viewer_plus: ^1.5.0 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_launcher_icons: "^0.12.0" + +flutter_icons: + android: true + ios: true + image_path: "assets/icon/icon2.png" +# 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. +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: + - assets/images/ + - assets/icon/ + - assets/homescreen/ + - assets/introduction_animation/ + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + fonts: + - family: WorkSans + fonts: + - asset: assets/fonts/WorkSans-Regular.ttf + - asset: assets/fonts/WorkSans-Medium.ttf + weight: 500 + - asset: assets/fonts/WorkSans-SemiBold.ttf + weight: 600 + - asset: assets/fonts/WorkSans-Bold.ttf + weight: 700 + - family: Roboto + fonts: + - asset: assets/fonts/Roboto-Bold.ttf + - asset: assets/fonts/Roboto-Regular.ttf + - asset: assets/fonts/Roboto-Medium.ttf + weight: 400 + - family: Inter + fonts: + - asset: assets/fonts/Inter-ExtraLight.ttf + weight: 200 + - asset: assets/fonts/Inter-Light.ttf + weight: 300 + - asset: assets/fonts/Inter-Regular.ttf + weight: 400 + - asset: assets/fonts/Inter-Medium.ttf + weight: 500 + - asset: assets/fonts/Inter-SemiBold.ttf + weight: 600 + - asset: assets/fonts/Inter-Bold.ttf + weight: 700 + - asset: assets/fonts/Inter-ExtraBold.ttf + weight: 800 + - asset: assets/fonts/Inter-Black.ttf + weight: 900 + + + + + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/test/widget_test.dart b/test/widget_test.dart new file mode 100644 index 0000000..6572696 --- /dev/null +++ b/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. 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:best_flutter_ui_templates/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(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); + }); +}