diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9d532b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..24544cb --- /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: 84f3d28555368a70270e9ac8390a9441df95e752 + channel: stable + +project_type: app diff --git a/README.md b/README.md new file mode 100644 index 0000000..254f737 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# Instagram Flutter + +A new Flutter project πŸ”₯πŸ”₯πŸ”₯ + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +| | | +|:----|:----| +|![](./sample/Screenshot_1614271249.png)|![](./sample/Screenshot_1614271261.png)| +|![](./sample/Screenshot_1614271272.png)|![](./sample/Screenshot_1614271279.png)| +|![](./sample/Screenshot_1614271300.png)|![](./sample/Screenshot_1614271317.png)| +|![](./sample/Screenshot_1614271544.png)|![](./sample/Screenshot_1614271565.png)| +|![](./sample/Screenshot_1614271573.png)|![](./sample/Screenshot_1614271598.png)| +|![](./sample/Screenshot_1614271609.png)|![]()| \ No newline at end of file diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..0a741cb --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,11 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000..9db46df --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,63 @@ +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 29 + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.flutter_new_instagram" + minSdkVersion 21 + targetSdkVersion 29 + 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" +} diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..744297a --- /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..322faba --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/kotlin/com/example/flutter_new_instagram/MainActivity.kt b/android/app/src/main/kotlin/com/example/flutter_new_instagram/MainActivity.kt new file mode 100644 index 0000000..0cd53ca --- /dev/null +++ b/android/app/src/main/kotlin/com/example/flutter_new_instagram/MainActivity.kt @@ -0,0 +1,6 @@ +package com.example.flutter_new_instagram + +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..db77bb4 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..17987b7 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..09d4391 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..d5f1c8d 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..4d6372e 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..744297a --- /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..3100ad2 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,31 @@ +buildscript { + ext.kotlin_version = '1.3.50' + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.5.0' + 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..a673820 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true +android.enableR8=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..296b146 --- /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-5.6.2-all.zip diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..44e62bc --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/assets/images/home-24px.svg b/assets/images/home-24px.svg new file mode 100644 index 0000000..b3bbd60 --- /dev/null +++ b/assets/images/home-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/ic_aa_text.svg b/assets/images/ic_aa_text.svg new file mode 100644 index 0000000..d0c8041 --- /dev/null +++ b/assets/images/ic_aa_text.svg @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/assets/images/ic_account.svg b/assets/images/ic_account.svg new file mode 100644 index 0000000..289f168 --- /dev/null +++ b/assets/images/ic_account.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/ic_account_selected.svg b/assets/images/ic_account_selected.svg new file mode 100644 index 0000000..3ff9e21 --- /dev/null +++ b/assets/images/ic_account_selected.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/ic_add_circle.svg b/assets/images/ic_add_circle.svg new file mode 100644 index 0000000..27529b0 --- /dev/null +++ b/assets/images/ic_add_circle.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/ic_add_new.svg b/assets/images/ic_add_new.svg new file mode 100644 index 0000000..96e0b2d --- /dev/null +++ b/assets/images/ic_add_new.svg @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/assets/images/ic_art.svg b/assets/images/ic_art.svg new file mode 100644 index 0000000..12b86ea --- /dev/null +++ b/assets/images/ic_art.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/ic_bookmark.svg b/assets/images/ic_bookmark.svg new file mode 100644 index 0000000..dc95d34 --- /dev/null +++ b/assets/images/ic_bookmark.svg @@ -0,0 +1,16 @@ + + + + + + + diff --git a/assets/images/ic_camera.svg b/assets/images/ic_camera.svg new file mode 100644 index 0000000..13c62e1 --- /dev/null +++ b/assets/images/ic_camera.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/ic_camera_v2.svg b/assets/images/ic_camera_v2.svg new file mode 100644 index 0000000..2ea785d --- /dev/null +++ b/assets/images/ic_camera_v2.svg @@ -0,0 +1,25 @@ + + + + + + + + diff --git a/assets/images/ic_comment.svg b/assets/images/ic_comment.svg new file mode 100644 index 0000000..b18e4cd --- /dev/null +++ b/assets/images/ic_comment.svg @@ -0,0 +1,10 @@ + + + Created by Sofia Espino-Yaeger + from the Noun Project \ No newline at end of file diff --git a/assets/images/ic_comment_outline.svg b/assets/images/ic_comment_outline.svg new file mode 100644 index 0000000..b8cd447 --- /dev/null +++ b/assets/images/ic_comment_outline.svg @@ -0,0 +1,13 @@ + + + + + + + diff --git a/assets/images/ic_comment_v3.svg b/assets/images/ic_comment_v3.svg new file mode 100644 index 0000000..3863257 --- /dev/null +++ b/assets/images/ic_comment_v3.svg @@ -0,0 +1,16 @@ + + + + + + + diff --git a/assets/images/ic_create_post.svg b/assets/images/ic_create_post.svg new file mode 100644 index 0000000..9d072bb --- /dev/null +++ b/assets/images/ic_create_post.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/ic_expand.svg b/assets/images/ic_expand.svg new file mode 100644 index 0000000..fbaea47 --- /dev/null +++ b/assets/images/ic_expand.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/ic_facebook.svg b/assets/images/ic_facebook.svg new file mode 100644 index 0000000..079e2b9 --- /dev/null +++ b/assets/images/ic_facebook.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/ic_favorite.svg b/assets/images/ic_favorite.svg new file mode 100644 index 0000000..5fa6ce4 --- /dev/null +++ b/assets/images/ic_favorite.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/ic_favorite_selected.svg b/assets/images/ic_favorite_selected.svg new file mode 100644 index 0000000..50c79c6 --- /dev/null +++ b/assets/images/ic_favorite_selected.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/ic_feed_post.svg b/assets/images/ic_feed_post.svg new file mode 100644 index 0000000..4148b42 --- /dev/null +++ b/assets/images/ic_feed_post.svg @@ -0,0 +1,19 @@ + + + + + + + diff --git a/assets/images/ic_filter_color.svg b/assets/images/ic_filter_color.svg new file mode 100644 index 0000000..fb18973 --- /dev/null +++ b/assets/images/ic_filter_color.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + diff --git a/assets/images/ic_filter_crop.svg b/assets/images/ic_filter_crop.svg new file mode 100644 index 0000000..b9b5f68 --- /dev/null +++ b/assets/images/ic_filter_crop.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + diff --git a/assets/images/ic_filter_face.svg b/assets/images/ic_filter_face.svg new file mode 100644 index 0000000..2ea2d15 --- /dev/null +++ b/assets/images/ic_filter_face.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + diff --git a/assets/images/ic_food.svg b/assets/images/ic_food.svg new file mode 100644 index 0000000..25ce86c --- /dev/null +++ b/assets/images/ic_food.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/ic_gallery.svg b/assets/images/ic_gallery.svg new file mode 100644 index 0000000..d333557 --- /dev/null +++ b/assets/images/ic_gallery.svg @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/assets/images/ic_guide.svg b/assets/images/ic_guide.svg new file mode 100644 index 0000000..0ef3c46 --- /dev/null +++ b/assets/images/ic_guide.svg @@ -0,0 +1,29 @@ + + + + + + + + + + diff --git a/assets/images/ic_heart_filled.svg b/assets/images/ic_heart_filled.svg new file mode 100644 index 0000000..a774223 --- /dev/null +++ b/assets/images/ic_heart_filled.svg @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/assets/images/ic_heart_outline.svg b/assets/images/ic_heart_outline.svg new file mode 100644 index 0000000..bd7fee6 --- /dev/null +++ b/assets/images/ic_heart_outline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/ic_heart_v2.svg b/assets/images/ic_heart_v2.svg new file mode 100644 index 0000000..1520ae6 --- /dev/null +++ b/assets/images/ic_heart_v2.svg @@ -0,0 +1,15 @@ + + + + + + + diff --git a/assets/images/ic_home.svg b/assets/images/ic_home.svg new file mode 100644 index 0000000..f1ef0a0 --- /dev/null +++ b/assets/images/ic_home.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/ic_home_selected.svg b/assets/images/ic_home_selected.svg new file mode 100644 index 0000000..1b3702d --- /dev/null +++ b/assets/images/ic_home_selected.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/ic_igtv_video.svg b/assets/images/ic_igtv_video.svg new file mode 100644 index 0000000..4a5d9fb --- /dev/null +++ b/assets/images/ic_igtv_video.svg @@ -0,0 +1,24 @@ + + + + + + + + diff --git a/assets/images/ic_insta_splash.svg b/assets/images/ic_insta_splash.svg new file mode 100644 index 0000000..357f7f2 --- /dev/null +++ b/assets/images/ic_insta_splash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/ic_instagram.svg b/assets/images/ic_instagram.svg new file mode 100644 index 0000000..ead9b37 --- /dev/null +++ b/assets/images/ic_instagram.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/ic_mesenger.svg b/assets/images/ic_mesenger.svg new file mode 100644 index 0000000..10b3840 --- /dev/null +++ b/assets/images/ic_mesenger.svg @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/assets/images/ic_multi.svg b/assets/images/ic_multi.svg new file mode 100644 index 0000000..e34ef27 --- /dev/null +++ b/assets/images/ic_multi.svg @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/assets/images/ic_music.svg b/assets/images/ic_music.svg new file mode 100644 index 0000000..7bad646 --- /dev/null +++ b/assets/images/ic_music.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/ic_play.svg b/assets/images/ic_play.svg new file mode 100644 index 0000000..5d60f51 --- /dev/null +++ b/assets/images/ic_play.svg @@ -0,0 +1,12 @@ + + + + + + + diff --git a/assets/images/ic_profile_add.svg b/assets/images/ic_profile_add.svg new file mode 100644 index 0000000..d8e9520 --- /dev/null +++ b/assets/images/ic_profile_add.svg @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/assets/images/ic_profile_new.svg b/assets/images/ic_profile_new.svg new file mode 100644 index 0000000..b6a65b8 --- /dev/null +++ b/assets/images/ic_profile_new.svg @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/assets/images/ic_rotate_camera.svg b/assets/images/ic_rotate_camera.svg new file mode 100644 index 0000000..cfaea31 --- /dev/null +++ b/assets/images/ic_rotate_camera.svg @@ -0,0 +1,29 @@ + + + + + + + + + diff --git a/assets/images/ic_search.svg b/assets/images/ic_search.svg new file mode 100644 index 0000000..3642b19 --- /dev/null +++ b/assets/images/ic_search.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/ic_search_new.svg b/assets/images/ic_search_new.svg new file mode 100644 index 0000000..1ace05f --- /dev/null +++ b/assets/images/ic_search_new.svg @@ -0,0 +1,14 @@ + + + + + + + diff --git a/assets/images/ic_search_selected.svg b/assets/images/ic_search_selected.svg new file mode 100644 index 0000000..077f1c4 --- /dev/null +++ b/assets/images/ic_search_selected.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/ic_send.svg b/assets/images/ic_send.svg new file mode 100644 index 0000000..d98f225 --- /dev/null +++ b/assets/images/ic_send.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/ic_send_direct.svg b/assets/images/ic_send_direct.svg new file mode 100644 index 0000000..cc09e28 --- /dev/null +++ b/assets/images/ic_send_direct.svg @@ -0,0 +1,17 @@ + + + + + + + diff --git a/assets/images/ic_send_v3.svg b/assets/images/ic_send_v3.svg new file mode 100644 index 0000000..1ad9929 --- /dev/null +++ b/assets/images/ic_send_v3.svg @@ -0,0 +1,15 @@ + + + + + + + diff --git a/assets/images/ic_setting.svg b/assets/images/ic_setting.svg new file mode 100644 index 0000000..a14178f --- /dev/null +++ b/assets/images/ic_setting.svg @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/assets/images/ic_shop.svg b/assets/images/ic_shop.svg new file mode 100644 index 0000000..e8442bc --- /dev/null +++ b/assets/images/ic_shop.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/ic_story.svg b/assets/images/ic_story.svg new file mode 100644 index 0000000..5a63f6e --- /dev/null +++ b/assets/images/ic_story.svg @@ -0,0 +1,24 @@ + + + + + + + + + diff --git a/assets/images/ic_story_highlight.svg b/assets/images/ic_story_highlight.svg new file mode 100644 index 0000000..2b43023 --- /dev/null +++ b/assets/images/ic_story_highlight.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + diff --git a/assets/images/ic_style.svg b/assets/images/ic_style.svg new file mode 100644 index 0000000..e5dea14 --- /dev/null +++ b/assets/images/ic_style.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/ic_travel.svg b/assets/images/ic_travel.svg new file mode 100644 index 0000000..ff90fe0 --- /dev/null +++ b/assets/images/ic_travel.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/images_sample.jpg b/assets/images/images_sample.jpg new file mode 100644 index 0000000..10c28a3 Binary files /dev/null and b/assets/images/images_sample.jpg differ diff --git a/assets/images/images_sample_2.jpg b/assets/images/images_sample_2.jpg new file mode 100644 index 0000000..238c846 Binary files /dev/null and b/assets/images/images_sample_2.jpg differ diff --git a/assets/images/logo_insta.svg b/assets/images/logo_insta.svg new file mode 100644 index 0000000..8e7e9f8 --- /dev/null +++ b/assets/images/logo_insta.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + 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..e8efba1 --- /dev/null +++ b/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..399e934 --- /dev/null +++ b/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/ios/Podfile b/ios/Podfile new file mode 100644 index 0000000..1e8c3c9 --- /dev/null +++ b/ios/Podfile @@ -0,0 +1,41 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..264d5b7 --- /dev/null +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,495 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + 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 */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 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 = 1020; + 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.flutterNewInstagram; + 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.flutterNewInstagram; + 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.flutterNewInstagram; + 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..1d526a1 --- /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..a28140c --- /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..dc9ada4 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..28c6bf0 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..2ccbfd9 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..f091b6b 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..4cde121 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..d0ef06e 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..dcdc230 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..2ccbfd9 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..c8f9ed8 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..a6d6b86 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-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..a6d6b86 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..75b2d16 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-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..c4df70d 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..6a84f41 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..d0e1f58 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/Info.plist b/ios/Runner/Info.plist new file mode 100644 index 0000000..bd93e79 --- /dev/null +++ b/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flutter_new_instagram + 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/lib/app/dummy/dummy.dart b/lib/app/dummy/dummy.dart new file mode 100644 index 0000000..f885c88 --- /dev/null +++ b/lib/app/dummy/dummy.dart @@ -0,0 +1,72 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/app/pages/comment/widget/comment_widget.dart'; +import 'package:flutter_new_instagram/app/pages/explore/widgets/explore_item_widget.dart'; + +List exploreListDummy() { + return [ + ExploreItemWidget( + 'https://wallpapercave.com/wp/wp3156022.jpg', ExploreType.VIDEO), + ExploreItemWidget( + 'https://wallpapercave.com/uwp/uwp9990.png', ExploreType.SINGLE_IMAGE), + ExploreItemWidget( + 'https://wallpapercave.com/wp/wp3856709.jpg', ExploreType.MULTI_IMAGE), + ExploreItemWidget( + 'https://wallpapercave.com/wp/wp7804681.jpg', ExploreType.SINGLE_IMAGE), + ExploreItemWidget( + 'https://wallpapercave.com/wp/wp3856716.png', ExploreType.MULTI_IMAGE), + ExploreItemWidget( + 'https://wallpapercave.com/wp/wp5376668.png', ExploreType.VIDEO), + ExploreItemWidget( + 'https://wallpapercave.com/wp/wp7804706.jpg', ExploreType.MULTI_IMAGE), + ExploreItemWidget( + 'https://wallpapercave.com/wp/wp2471312.jpg', ExploreType.SINGLE_IMAGE), + ExploreItemWidget( + 'https://wallpapercave.com/wp/wp6363703.png', ExploreType.MULTI_IMAGE), + ExploreItemWidget('https://wallpapercave.com/uwp/uwp131677.jpeg', + ExploreType.SINGLE_IMAGE), + ]; +} + +List commentListDummy() { + return [ + CommentWidget( + sender: 'oldfartmel', message: ' same high class you show :D'), + CommentWidget(sender: '_itz_about_quotes_', message: ' ❀️'), + CommentWidget(sender: '943.aleksei', message: ' ❀️❀️'), + CommentWidget(sender: 'min_', message: ' πŸ‚β„β„οΈ'), + CommentWidget( + sender: 'oldfartmel', + message: + ' Keep your eyes on your end goal, amazing post keep up the good workπŸ”₯'), + CommentWidget(sender: 'sidneyporten', message: ' Great post!!!') + ]; +} + +List emojiListDummy() { + return [ + Text('πŸ€—', style: TextStyle(fontSize: 20)), + Text('πŸ˜€', style: TextStyle(fontSize: 20)), + Text('🀩', style: TextStyle(fontSize: 20)), + Text('πŸ‘»', style: TextStyle(fontSize: 20)), + Text('☠️', style: TextStyle(fontSize: 20)), + Text('πŸ˜™', style: TextStyle(fontSize: 20)), + Text('πŸ€‘', style: TextStyle(fontSize: 20)), + Text('πŸ˜€', style: TextStyle(fontSize: 20)), + Text('🀩', style: TextStyle(fontSize: 20)), + Text('πŸ‘»', style: TextStyle(fontSize: 20)), + Text('πŸ€‘', style: TextStyle(fontSize: 20)), + Text('πŸ˜™', style: TextStyle(fontSize: 20)) + ]; +} + +List locationListSuggest() { + return [ + Chip(label: Text('Da Nang')), + Chip(label: Text('Hoi An')), + Chip(label: Text('Nha Trang')), + Chip(label: Text('Mui Ne')), + Chip(label: Text('Ha Noi')), + Chip(label: Text('Ha Long Bay')), + Chip(label: Text('Hue')) + ]; +} diff --git a/lib/app/main.dart b/lib/app/main.dart new file mode 100644 index 0000000..adb85cb --- /dev/null +++ b/lib/app/main.dart @@ -0,0 +1,131 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/app/pages/splash/splash_screen.dart'; +import 'package:get/get.dart'; + +void main() { + runApp(InstaApplication()); +} + +class InstaApplication extends StatefulWidget { + @override + _InstaApplicationState createState() => _InstaApplicationState(); +} + +class _InstaApplicationState extends State { + @override + Widget build(BuildContext context) { + return GetMaterialApp(home: SplashScreen()); + } +} + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + // This is the theme of your application. + // + // Try running your application with "flutter run". You'll see the + // application has a blue toolbar. Then, without quitting the app, try + // changing the primarySwatch below to Colors.green and then invoke + // "hot reload" (press "r" in the console where you ran "flutter run", + // or simply save your changes to "hot reload" in a Flutter IDE). + // Notice that the counter didn't reset back to zero; the application + // is not restarted. + primarySwatch: Colors.blue, + // This makes the visual density adapt to the platform that you run + // the app on. For desktop platforms, the controls will be smaller and + // closer together (more dense) than on mobile platforms. + visualDensity: VisualDensity.adaptivePlatformDensity, + ), + home: MyHomePage(title: 'Flutter Demo Home Page'), + ); + } +} + +class MyHomePage extends StatefulWidget { + MyHomePage({Key key, this.title}) : super(key: key); + + // This widget is the home page of your application. It is stateful, meaning + // that it has a State object (defined below) that contains fields that affect + // how it looks. + + // This class is the configuration for the state. It holds the values (in this + // case the title) provided by the parent (in this case the App widget) and + // used by the build method of the State. Fields in a Widget subclass are + // always marked "final". + + final String title; + + @override + _MyHomePageState createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + int _counter = 0; + + void _incrementCounter() { + setState(() { + // This call to setState tells the Flutter framework that something has + // changed in this State, which causes it to rerun the build method below + // so that the display can reflect the updated values. If we changed + // _counter without calling setState(), then the build method would not be + // called again, and so nothing would appear to happen. + _counter++; + }); + } + + @override + Widget build(BuildContext context) { + // This method is rerun every time setState is called, for instance as done + // by the _incrementCounter method above. + // + // The Flutter framework has been optimized to make rerunning build methods + // fast, so that you can just rebuild anything that needs updating rather + // than having to individually change instances of widgets. + return Scaffold( + appBar: AppBar( + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: Text(widget.title), + ), + body: Center( + // Center is a layout widget. It takes a single child and positions it + // in the middle of the parent. + child: Column( + // Column is also a layout widget. It takes a list of children and + // arranges them vertically. By default, it sizes itself to fit its + // children horizontally, and tries to be as tall as its parent. + // + // Invoke "debug painting" (press "p" in the console, choose the + // "Toggle Debug Paint" action from the Flutter Inspector in Android + // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) + // to see the wireframe for each widget. + // + // Column has various properties to control how it sizes itself and + // how it positions its children. Here we use mainAxisAlignment to + // center the children vertically; the main axis here is the vertical + // axis because Columns are vertical (the cross axis would be + // horizontal). + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'You have pushed the button this many times:', + ), + Text( + '$_counter', + style: Theme.of(context).textTheme.headline4, + ), + ], + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: _incrementCounter, + tooltip: 'Increment', + child: Icon(Icons.add), + ), // This trailing comma makes auto-formatting nicer for build methods. + ); + } +} diff --git a/lib/app/pages/activity/activity_screen.dart b/lib/app/pages/activity/activity_screen.dart new file mode 100644 index 0000000..67b8aa0 --- /dev/null +++ b/lib/app/pages/activity/activity_screen.dart @@ -0,0 +1,92 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/app/pages/activity/widgets/activity_log_item.dart'; +import 'package:flutter_new_instagram/app/pages/activity/widgets/follow_request_widget.dart'; + +class ActivityScreen extends StatefulWidget { + @override + _ActivityScreenState createState() => _ActivityScreenState(); +} + +class _ActivityScreenState extends State { + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top), + child: Scaffold( + appBar: PreferredSize( + preferredSize: Size.fromHeight(22), + child: Container( + alignment: Alignment.center, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + height: 44, + alignment: Alignment.center, + child: Text( + 'Activity', + style: + TextStyle(fontSize: 16, fontWeight: FontWeight.w500), + ), + ), + Container( + height: 0.5, + color: Colors.grey, + ) + ], + )), + ), + body: RefreshIndicator( + onRefresh: () async { + await Future.delayed(Duration(seconds: 1)); + }, + child: CustomScrollView( + slivers: [ + SliverPersistentHeader( + pinned: false, + floating: false, + delegate: SliverFollowRequestWidget()), + SliverList( + delegate: SliverChildBuilderDelegate((context, index) { + return Column( + children: [ + _itemList()[index].buildItem(), + SizedBox(height: 10), + ], + ); + }, childCount: _itemList().length)) + ], + ), + ), + ), + ); + } + + List _itemList() { + List items = []; + items.add(ActivityLogTimeItem('Today')); + items.add(ActivityLogContentItem(2)); + items.add(ActivityLogContentItem(1)); + items.add(ActivityLogContentItem(2)); + items.add(ActivityLogContentItem(3)); + items.add(ActivityLogContentItem(2)); + items.add(ActivityLogTimeItem('Yesterday')); + items.add(ActivityLogContentItem(1)); + items.add(ActivityLogContentItem(1)); + items.add(ActivityLogTimeItem('This Week')); + items.add(ActivityLogContentItem(1)); + items.add(ActivityLogContentItem(1)); + items.add(ActivityLogContentItem(1)); + items.add(ActivityLogContentItem(1)); + items.add(ActivityLogContentItem(1)); + items.add(ActivityLogContentItem(1)); + items.add(ActivityLogTimeItem('This Month')); + items.add(ActivityLogContentItem(2)); + items.add(ActivityLogContentItem(2)); + items.add(ActivityLogContentItem(2)); + items.add(ActivityLogContentItem(2)); + items.add(ActivityLogTimeItem('Ealier')); + items.add(ActivityLogContentItem(2)); + return items; + } +} diff --git a/lib/app/pages/activity/widgets/activity_log_item.dart b/lib/app/pages/activity/widgets/activity_log_item.dart new file mode 100644 index 0000000..1fa5c17 --- /dev/null +++ b/lib/app/pages/activity/widgets/activity_log_item.dart @@ -0,0 +1,262 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; + +abstract class ActivityLogItem { + Widget buildItem(); +} + +class ActivityLogTimeItem implements ActivityLogItem { + final String dateTime; + + ActivityLogTimeItem(this.dateTime); + + @override + Widget buildItem() { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 8.0), + child: Container( + alignment: Alignment.centerLeft, + child: Text( + dateTime, + style: TextStyle( + color: Colors.black, fontSize: 19, fontWeight: FontWeight.w500), + ), + ), + ); + } +} + +class ActivityLogContentItem implements ActivityLogItem { + final int type; + + ActivityLogContentItem(this.type); + + @override + Widget buildItem() { + switch (type) { + case 1: + { + return _buildLogType1(); + } + case 2: + { + return _buildLogType2(); + } + case 3: + { + return _buildLogType3(); + } + default: + { + return SizedBox(); + } + } + } + + Widget _buildLogType1() { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + CircleAvatar( + radius: 20, + backgroundImage: Assets.images.imagesSample, + ), + SizedBox(width: 16), + Expanded( + child: RichText( + maxLines: 2, + text: TextSpan( + text: '', + style: TextStyle( + fontWeight: FontWeight.w300, + color: Colors.black, + height: 1.2, + fontSize: 13), + children: [ + TextSpan( + text: 'cuong_lo_renn', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w500)), + TextSpan( + text: ', ', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w300)), + TextSpan( + text: 'Hades', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w500)), + TextSpan( + text: ' and ', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w300)), + TextSpan( + text: 'bump.gethigh', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w500)), + TextSpan( + text: ' liked your photo', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w300)), + TextSpan( + text: '. 1h', + style: TextStyle( + color: Colors.grey, fontWeight: FontWeight.w300)), + ]), + ), + ), + SizedBox(width: 20), + Container( + width: 60, + height: 60, + child: ClipRRect( + borderRadius: BorderRadius.circular(8), + child: CachedNetworkImage( + imageUrl: 'https://wallpapercave.com/uwp/uwp9990.png', + fit: BoxFit.cover), + ), + ), + ], + ), + ), + ); + } + + Widget _buildLogType2() { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + CircleAvatar( + radius: 20, + backgroundImage: Assets.images.imagesSample2, + ), + SizedBox(width: 16), + Expanded( + child: RichText( + maxLines: 2, + text: TextSpan( + text: 'Since you follow ', + style: TextStyle( + fontWeight: FontWeight.w300, + color: Colors.black, + height: 1.2, + fontSize: 13), + children: [ + TextSpan( + text: 'Lionel Messi', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w500)), + TextSpan( + text: ', you might like ', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w300)), + TextSpan( + text: 'Cristiano Ronaldo', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w500)), + TextSpan( + text: '. 1h', + style: TextStyle( + color: Colors.grey, fontWeight: FontWeight.w300)), + ]), + ), + ), + SizedBox(width: 20), + ButtonTheme( + height: 27, + minWidth: 30, + child: RaisedButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6.0), + ), + textColor: Colors.white, + color: Colors.blue, + onPressed: () => {}, + child: Text( + "Follow", + style: TextStyle(color: Colors.white, fontSize: 13.0), + ), + ), + ), + ], + ), + ), + ); + } + + Widget _buildLogType3() { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 10).copyWith(right: 10), + child: Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + CircleAvatar( + radius: 20, + backgroundImage: Assets.images.imagesSample, + ), + SizedBox(width: 16), + Expanded( + child: RichText( + maxLines: 2, + text: TextSpan( + text: '', + style: TextStyle( + fontWeight: FontWeight.w300, + color: Colors.black, + height: 1.28, + fontSize: 13), + children: [ + TextSpan( + text: 'lady.bibiho_93', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w500)), + TextSpan( + text: ', ', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w300)), + TextSpan( + text: 'MiCheal Riz Kul', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w500)), + TextSpan( + text: ' and others shared 124 photos πŸ‰ πŸ’₯ 🐾 🐾 πŸ„', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w300)), + TextSpan( + text: '. 1h', + style: TextStyle( + color: Colors.grey, fontWeight: FontWeight.w300)), + ]), + ), + ), + SizedBox(width: 20), + ], + ), + ), + ); + } +} diff --git a/lib/app/pages/activity/widgets/activity_log_widget.dart b/lib/app/pages/activity/widgets/activity_log_widget.dart new file mode 100644 index 0000000..5cb9418 --- /dev/null +++ b/lib/app/pages/activity/widgets/activity_log_widget.dart @@ -0,0 +1,14 @@ +import 'package:flutter/material.dart'; + +class SliverActivityLogWidget extends StatefulWidget { + @override + _SliverActivityLogWidgetState createState() => + _SliverActivityLogWidgetState(); +} + +class _SliverActivityLogWidgetState extends State { + @override + Widget build(BuildContext context) { + return Container(); + } +} \ No newline at end of file diff --git a/lib/app/pages/activity/widgets/follow_request_widget.dart b/lib/app/pages/activity/widgets/follow_request_widget.dart new file mode 100644 index 0000000..4a495bd --- /dev/null +++ b/lib/app/pages/activity/widgets/follow_request_widget.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; + +class SliverFollowRequestWidget extends SliverPersistentHeaderDelegate { + @override + Widget build( + BuildContext context, double shrinkOffset, bool overlapsContent) { + return Container( + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 12, vertical: 16), + child: Text( + 'Follow Requests', + style: TextStyle(fontWeight: FontWeight.w400, fontSize: 14.5), + ), + ), + Spacer(), + CircleAvatar( + radius: 5, + backgroundColor: Colors.blue, + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Text('1,234'), + ) + ], + ), + Container(height: 0.3, color: Colors.grey[400]) + ], + ), + ); + } + + @override + double get maxExtent => 50; + + @override + double get minExtent => 50; + + @override + bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) { + return true; + } +} diff --git a/lib/app/pages/auth/auth_screen.dart b/lib/app/pages/auth/auth_screen.dart new file mode 100644 index 0000000..343c4cf --- /dev/null +++ b/lib/app/pages/auth/auth_screen.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +class AuthScreen extends StatefulWidget { + @override + _AuthScreenState createState() => _AuthScreenState(); +} + +class _AuthScreenState extends State { + @override + Widget build(BuildContext context) { + return Container(); + } +} diff --git a/lib/app/pages/camera/camera_screen.dart b/lib/app/pages/camera/camera_screen.dart new file mode 100644 index 0000000..83613ff --- /dev/null +++ b/lib/app/pages/camera/camera_screen.dart @@ -0,0 +1,933 @@ +import 'dart:async'; + +import 'package:camera/camera.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; +import 'dart:developer' as developer; + +import 'package:flutter_svg/flutter_svg.dart'; + +class CameraScreen extends StatefulWidget { + final List cameras; + + const CameraScreen(this.cameras); + + @override + _CameraScreenState createState() { + return _CameraScreenState(); + } +} + +class _CameraScreenState extends State + with WidgetsBindingObserver, TickerProviderStateMixin { + CameraController controller; + XFile imageFile; + XFile videoFile; + VoidCallback videoPlayerListener; + bool enableAudio = true; + double _minAvailableExposureOffset = 0.0; + double _maxAvailableExposureOffset = 0.0; + double _currentExposureOffset = 0.0; + AnimationController _flashModeControlRowAnimationController; + Animation _flashModeControlRowAnimation; + AnimationController _exposureModeControlRowAnimationController; + Animation _exposureModeControlRowAnimation; + AnimationController _focusModeControlRowAnimationController; + Animation _focusModeControlRowAnimation; + double _minAvailableZoom; + double _maxAvailableZoom; + double _currentScale = 1.0; + double _baseScale = 1.0; + + // Counting pointers (number of user fingers on screen) + int _pointers = 0; + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addObserver(this); + _flashModeControlRowAnimationController = AnimationController( + duration: const Duration(milliseconds: 300), + vsync: this, + ); + _flashModeControlRowAnimation = CurvedAnimation( + parent: _flashModeControlRowAnimationController, + curve: Curves.easeInCubic, + ); + _exposureModeControlRowAnimationController = AnimationController( + duration: const Duration(milliseconds: 300), + vsync: this, + ); + _exposureModeControlRowAnimation = CurvedAnimation( + parent: _exposureModeControlRowAnimationController, + curve: Curves.easeInCubic, + ); + _focusModeControlRowAnimationController = AnimationController( + duration: const Duration(milliseconds: 300), + vsync: this, + ); + _focusModeControlRowAnimation = CurvedAnimation( + parent: _focusModeControlRowAnimationController, + curve: Curves.easeInCubic, + ); + Future.delayed(Duration(milliseconds: 500)).then((value) { + onNewCameraSelected(widget.cameras.first); + }); + } + + @override + void dispose() { + WidgetsBinding.instance.removeObserver(this); + _flashModeControlRowAnimationController.dispose(); + _exposureModeControlRowAnimationController.dispose(); + super.dispose(); + } + + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + // App state changed before we got the chance to initialize. + if (controller == null || !controller.value.isInitialized) { + return; + } + if (state == AppLifecycleState.inactive) { + controller?.dispose(); + } else if (state == AppLifecycleState.resumed) { + if (controller != null) { + onNewCameraSelected(controller.description); + } + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + children: [ + Container( + color: Colors.black, + child: Center( + child: _cameraPreviewWidget(), + ), + ), + Container( + padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top), + color: Colors.transparent, + child: Column( + children: [ + Row( + children: [ + SizedBox(width: 10), + SvgPicture.asset( + Assets.images.icSetting, + color: Colors.white, + width: 26, + height: 26, + ), + Spacer(), + SizedBox(width: 16), + IconButton( + icon: Icon(Icons.flash_auto_sharp, + color: Colors.white, size: 24), + onPressed: null), + Spacer(), + IconButton( + icon: Icon(Icons.close, color: Colors.white, size: 32), + onPressed: null), + ], + ), + Expanded( + child: Container( + alignment: Alignment.centerLeft, + color: Colors.transparent, + child: Padding( + padding: const EdgeInsets.all(16.0).copyWith(top: 80), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset(Assets.images.icAaText, + width: 24, height: 24, color: Colors.white), + SizedBox(height: 8), + SvgPicture.asset(Assets.images.icFilterFace, + width: 24, height: 24, color: Colors.white), + SizedBox(height: 8), + SvgPicture.asset(Assets.images.icFilterColor, + width: 24, height: 24, color: Colors.white), + SizedBox(height: 8), + SvgPicture.asset(Assets.images.icFilterCrop, + width: 24, height: 24, color: Colors.white), + SizedBox(height: 8), + SvgPicture.asset(Assets.images.icExpand, + width: 24, height: 24, color: Colors.white), + ], + ), + ), + )), + Row( + children: [ + Spacer(), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(35), + border: Border.all( + color: Colors.white, + width: 3, + ), + color: Colors.transparent), + width: 70, + height: 70, + child: Container( + child: Padding( + padding: EdgeInsets.all(2.0), + child: Container( + decoration: ShapeDecoration( + color: Colors.white, shape: CircleBorder()), + ), + )), + ), + Spacer() + ], + ), + SizedBox(height: 25), + Row( + children: [ + SizedBox(width: 16), + SvgPicture.asset( + Assets.images.icGallery, + color: Colors.white, + width: 30, + height: 30, + ), + Expanded( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.only(top: 1), + child: Text('POST', + style: TextStyle( + color: Colors.white70, + fontSize: 13, + fontWeight: FontWeight.w400)), + ), + SizedBox(width: 8), + Text('STORY', + style: Theme.of(context) + .textTheme + .bodyText2 + .copyWith( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w500)), + SizedBox(width: 8), + Padding( + padding: const EdgeInsets.only(top: 1.0), + child: Text('LIVE', + style: TextStyle( + color: Colors.white70, + fontSize: 13, + fontWeight: FontWeight.w400)), + ), + ], + )), + SvgPicture.asset( + Assets.images.icRotateCamera, + color: Colors.white, + width: 30, + height: 30, + ), + SizedBox(width: 14), + ], + ), + SizedBox(height: 10 + MediaQuery.of(context).padding.bottom) + ], + ), + ) + // _captureControlRowWidget(), + // _modeControlRowWidget(), + // Padding( + // padding: const EdgeInsets.all(5.0), + // child: Row( + // mainAxisAlignment: MainAxisAlignment.start, + // children: [ + // _cameraTogglesRowWidget(), + // _thumbnailWidget(), + // ], + // ), + // ), + ], + ), + ); + } + + /// Display the preview from the camera (or a message if the preview is not available). + Widget _cameraPreviewWidget() { + final size = MediaQuery.of(context).size; + final deviceRatio = size.width / size.height; + + if (controller == null || !controller.value.isInitialized) { + return const CircularProgressIndicator(); + } else { + return Listener( + onPointerDown: (_) => _pointers++, + onPointerUp: (_) => _pointers--, + child: Transform.scale( + scale: controller.value.aspectRatio / deviceRatio, + child: Center( + child: AspectRatio( + aspectRatio: controller.value.aspectRatio, + child: CameraPreview( + controller, + child: LayoutBuilder(builder: + (BuildContext context, BoxConstraints constraints) { + return GestureDetector( + behavior: HitTestBehavior.opaque, + onScaleStart: _handleScaleStart, + onScaleUpdate: _handleScaleUpdate, + onTapDown: (details) => + onViewFinderTap(details, constraints), + ); + }), + ), + ), + ), + ), + ); + } + } + + void _handleScaleStart(ScaleStartDetails details) { + _baseScale = _currentScale; + } + + Future _handleScaleUpdate(ScaleUpdateDetails details) async { + // When there are not exactly two fingers on screen don't scale + if (_pointers != 2) { + return; + } + + _currentScale = (_baseScale * details.scale) + .clamp(_minAvailableZoom, _maxAvailableZoom); + + await controller.setZoomLevel(_currentScale); + } + + /// Display the thumbnail of the captured image or video. + Widget _thumbnailWidget() { + return Expanded( + child: Align( + alignment: Alignment.centerRight, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container(), + ], + ), + ), + ); + } + + /// Display a bar with buttons to change the flash and exposure modes + Widget _modeControlRowWidget() { + return Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisSize: MainAxisSize.max, + children: [ + IconButton( + icon: Icon(Icons.flash_on), + color: Colors.blue, + onPressed: controller != null ? onFlashModeButtonPressed : null, + ), + IconButton( + icon: Icon(Icons.exposure), + color: Colors.blue, + onPressed: + controller != null ? onExposureModeButtonPressed : null, + ), + IconButton( + icon: Icon(Icons.filter_center_focus), + color: Colors.blue, + onPressed: controller != null ? onFocusModeButtonPressed : null, + ), + IconButton( + icon: Icon(enableAudio ? Icons.volume_up : Icons.volume_mute), + color: Colors.blue, + onPressed: controller != null ? onAudioModeButtonPressed : null, + ), + IconButton( + icon: Icon(controller?.value?.isCaptureOrientationLocked ?? false + ? Icons.screen_lock_rotation + : Icons.screen_rotation), + color: Colors.blue, + onPressed: controller != null + ? onCaptureOrientationLockButtonPressed + : null, + ), + ], + ), + _flashModeControlRowWidget(), + _exposureModeControlRowWidget(), + _focusModeControlRowWidget(), + ], + ); + } + + Widget _flashModeControlRowWidget() { + return SizeTransition( + sizeFactor: _flashModeControlRowAnimation, + child: ClipRect( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisSize: MainAxisSize.max, + children: [ + IconButton( + icon: Icon(Icons.flash_off), + color: controller?.value?.flashMode == FlashMode.off + ? Colors.orange + : Colors.blue, + onPressed: controller != null + ? () => onSetFlashModeButtonPressed(FlashMode.off) + : null, + ), + IconButton( + icon: Icon(Icons.flash_auto), + color: controller?.value?.flashMode == FlashMode.auto + ? Colors.orange + : Colors.blue, + onPressed: controller != null + ? () => onSetFlashModeButtonPressed(FlashMode.auto) + : null, + ), + IconButton( + icon: Icon(Icons.flash_on), + color: controller?.value?.flashMode == FlashMode.always + ? Colors.orange + : Colors.blue, + onPressed: controller != null + ? () => onSetFlashModeButtonPressed(FlashMode.always) + : null, + ), + IconButton( + icon: Icon(Icons.highlight), + color: controller?.value?.flashMode == FlashMode.torch + ? Colors.orange + : Colors.blue, + onPressed: controller != null + ? () => onSetFlashModeButtonPressed(FlashMode.torch) + : null, + ), + ], + ), + ), + ); + } + + Widget _exposureModeControlRowWidget() { + final ButtonStyle styleAuto = TextButton.styleFrom( + primary: controller?.value?.exposureMode == ExposureMode.auto + ? Colors.orange + : Colors.blue, + ); + final ButtonStyle styleLocked = TextButton.styleFrom( + primary: controller?.value?.exposureMode == ExposureMode.locked + ? Colors.orange + : Colors.blue, + ); + + return SizeTransition( + sizeFactor: _exposureModeControlRowAnimation, + child: ClipRect( + child: Container( + color: Colors.grey.shade50, + child: Column( + children: [ + Center( + child: Text("Exposure Mode"), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisSize: MainAxisSize.max, + children: [ + TextButton( + child: Text('AUTO'), + style: styleAuto, + onPressed: controller != null + ? () => + onSetExposureModeButtonPressed(ExposureMode.auto) + : null, + onLongPress: () { + if (controller != null) controller.setExposurePoint(null); + developer.log('Resetting exposure point'); + }, + ), + TextButton( + child: Text('LOCKED'), + style: styleLocked, + onPressed: controller != null + ? () => + onSetExposureModeButtonPressed(ExposureMode.locked) + : null, + ), + ], + ), + Center( + child: Text("Exposure Offset"), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisSize: MainAxisSize.max, + children: [ + Text(_minAvailableExposureOffset.toString()), + Slider( + value: _currentExposureOffset, + min: _minAvailableExposureOffset, + max: _maxAvailableExposureOffset, + label: _currentExposureOffset.toString(), + onChanged: _minAvailableExposureOffset == + _maxAvailableExposureOffset + ? null + : setExposureOffset, + ), + Text(_maxAvailableExposureOffset.toString()), + ], + ), + ], + ), + ), + ), + ); + } + + Widget _focusModeControlRowWidget() { + final ButtonStyle styleAuto = TextButton.styleFrom( + primary: controller?.value?.focusMode == FocusMode.auto + ? Colors.orange + : Colors.blue, + ); + final ButtonStyle styleLocked = TextButton.styleFrom( + primary: controller?.value?.focusMode == FocusMode.locked + ? Colors.orange + : Colors.blue, + ); + + return SizeTransition( + sizeFactor: _focusModeControlRowAnimation, + child: ClipRect( + child: Container( + color: Colors.grey.shade50, + child: Column( + children: [ + Center( + child: Text("Focus Mode"), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisSize: MainAxisSize.max, + children: [ + TextButton( + child: Text('AUTO'), + style: styleAuto, + onPressed: controller != null + ? () => onSetFocusModeButtonPressed(FocusMode.auto) + : null, + onLongPress: () { + if (controller != null) controller.setFocusPoint(null); + developer.log('Resetting focus point'); + }, + ), + TextButton( + child: Text('LOCKED'), + style: styleLocked, + onPressed: controller != null + ? () => onSetFocusModeButtonPressed(FocusMode.locked) + : null, + ), + ], + ), + ], + ), + ), + ), + ); + } + + /// Display the control bar with buttons to take pictures and record videos. + Widget _captureControlRowWidget() { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisSize: MainAxisSize.max, + children: [ + IconButton( + icon: const Icon(Icons.camera_alt), + color: Colors.blue, + onPressed: controller != null && + controller.value.isInitialized && + !controller.value.isRecordingVideo + ? onTakePictureButtonPressed + : null, + ), + IconButton( + icon: const Icon(Icons.videocam), + color: Colors.blue, + onPressed: controller != null && + controller.value.isInitialized && + !controller.value.isRecordingVideo + ? onVideoRecordButtonPressed + : null, + ), + IconButton( + icon: controller != null && controller.value.isRecordingPaused + ? Icon(Icons.play_arrow) + : Icon(Icons.pause), + color: Colors.blue, + onPressed: controller != null && + controller.value.isInitialized && + controller.value.isRecordingVideo + ? (controller != null && controller.value.isRecordingPaused + ? onResumeButtonPressed + : onPauseButtonPressed) + : null, + ), + IconButton( + icon: const Icon(Icons.stop), + color: Colors.red, + onPressed: controller != null && + controller.value.isInitialized && + controller.value.isRecordingVideo + ? onStopButtonPressed + : null, + ) + ], + ); + } + + /// Display a row of toggle to select the camera (or a message if no camera is available). + Widget _cameraTogglesRowWidget() { + final List toggles = []; + + if (widget.cameras.isEmpty) { + return const Text('No camera found'); + } else { + for (CameraDescription cameraDescription in widget.cameras) { + toggles.add( + SizedBox( + width: 90.0, + child: RadioListTile( + title: Icon(getCameraLensIcon(cameraDescription.lensDirection)), + groupValue: controller?.description, + value: cameraDescription, + onChanged: controller != null && controller.value.isRecordingVideo + ? null + : onNewCameraSelected, + ), + ), + ); + } + } + + return Row(children: toggles); + } + + String timestamp() => DateTime.now().millisecondsSinceEpoch.toString(); + + void onViewFinderTap(TapDownDetails details, BoxConstraints constraints) { + final offset = Offset( + details.localPosition.dx / constraints.maxWidth, + details.localPosition.dy / constraints.maxHeight, + ); + controller.setExposurePoint(offset); + controller.setFocusPoint(offset); + } + + void onNewCameraSelected(CameraDescription cameraDescription) async { + if (controller != null) { + await controller.dispose(); + } + controller = CameraController( + cameraDescription, + ResolutionPreset.medium, + enableAudio: enableAudio, + imageFormatGroup: ImageFormatGroup.jpeg, + ); + + // If the controller is updated then update the UI. + controller.addListener(() { + if (mounted) setState(() {}); + if (controller.value.hasError) { + developer.log('Camera error ${controller.value.errorDescription}'); + } + }); + + try { + await controller.initialize(); + await Future.wait([ + controller + .getMinExposureOffset() + .then((value) => _minAvailableExposureOffset = value), + controller + .getMaxExposureOffset() + .then((value) => _maxAvailableExposureOffset = value), + controller.getMaxZoomLevel().then((value) => _maxAvailableZoom = value), + controller.getMinZoomLevel().then((value) => _minAvailableZoom = value), + ]); + } on CameraException catch (e) { + _showCameraException(e); + } + + if (mounted) { + setState(() {}); + } + } + + void onTakePictureButtonPressed() { + takePicture().then((XFile file) { + if (mounted) { + setState(() { + imageFile = file; + }); + if (file != null) developer.log('Picture saved to ${file.path}'); + } + }); + } + + void onFlashModeButtonPressed() { + if (_flashModeControlRowAnimationController.value == 1) { + _flashModeControlRowAnimationController.reverse(); + } else { + _flashModeControlRowAnimationController.forward(); + _exposureModeControlRowAnimationController.reverse(); + _focusModeControlRowAnimationController.reverse(); + } + } + + void onExposureModeButtonPressed() { + if (_exposureModeControlRowAnimationController.value == 1) { + _exposureModeControlRowAnimationController.reverse(); + } else { + _exposureModeControlRowAnimationController.forward(); + _flashModeControlRowAnimationController.reverse(); + _focusModeControlRowAnimationController.reverse(); + } + } + + void onFocusModeButtonPressed() { + if (_focusModeControlRowAnimationController.value == 1) { + _focusModeControlRowAnimationController.reverse(); + } else { + _focusModeControlRowAnimationController.forward(); + _flashModeControlRowAnimationController.reverse(); + _exposureModeControlRowAnimationController.reverse(); + } + } + + void onAudioModeButtonPressed() { + enableAudio = !enableAudio; + if (controller != null) { + onNewCameraSelected(controller.description); + } + } + + void onCaptureOrientationLockButtonPressed() async { + if (controller != null) { + if (controller.value.isCaptureOrientationLocked) { + await controller.unlockCaptureOrientation(); + developer.log('Capture orientation unlocked'); + } else { + await controller.lockCaptureOrientation(); + developer.log( + 'Capture orientation locked to ${controller.value.lockedCaptureOrientation.toString().split('.').last}'); + } + } + } + + void onSetFlashModeButtonPressed(FlashMode mode) { + setFlashMode(mode).then((_) { + if (mounted) setState(() {}); + developer.log('Flash mode set to ${mode.toString().split('.').last}'); + }); + } + + void onSetExposureModeButtonPressed(ExposureMode mode) { + setExposureMode(mode).then((_) { + if (mounted) setState(() {}); + developer.log('Exposure mode set to ${mode.toString().split('.').last}'); + }); + } + + void onSetFocusModeButtonPressed(FocusMode mode) { + setFocusMode(mode).then((_) { + if (mounted) setState(() {}); + developer.log('Focus mode set to ${mode.toString().split('.').last}'); + }); + } + + void onVideoRecordButtonPressed() { + startVideoRecording().then((_) { + if (mounted) setState(() {}); + }); + } + + void onStopButtonPressed() { + stopVideoRecording().then((file) { + if (mounted) setState(() {}); + if (file != null) { + developer.log('Video recorded to ${file.path}'); + videoFile = file; + _startVideoPlayer(); + } + }); + } + + void onPauseButtonPressed() { + pauseVideoRecording().then((_) { + if (mounted) setState(() {}); + developer.log('Video recording paused'); + }); + } + + void onResumeButtonPressed() { + resumeVideoRecording().then((_) { + if (mounted) setState(() {}); + developer.log('Video recording resumed'); + }); + } + + Future startVideoRecording() async { + if (!controller.value.isInitialized) { + developer.log('Error: select a camera first.'); + return; + } + + if (controller.value.isRecordingVideo) { + // A recording is already started, do nothing. + return; + } + + try { + await controller.startVideoRecording(); + } on CameraException catch (e) { + _showCameraException(e); + return; + } + } + + Future stopVideoRecording() async { + if (!controller.value.isRecordingVideo) { + return null; + } + + try { + return controller.stopVideoRecording(); + } on CameraException catch (e) { + _showCameraException(e); + return null; + } + } + + Future pauseVideoRecording() async { + if (!controller.value.isRecordingVideo) { + return null; + } + + try { + await controller.pauseVideoRecording(); + } on CameraException catch (e) { + _showCameraException(e); + rethrow; + } + } + + Future resumeVideoRecording() async { + if (!controller.value.isRecordingVideo) { + return null; + } + + try { + await controller.resumeVideoRecording(); + } on CameraException catch (e) { + _showCameraException(e); + rethrow; + } + } + + Future setFlashMode(FlashMode mode) async { + try { + await controller.setFlashMode(mode); + } on CameraException catch (e) { + _showCameraException(e); + rethrow; + } + } + + Future setExposureMode(ExposureMode mode) async { + try { + await controller.setExposureMode(mode); + } on CameraException catch (e) { + _showCameraException(e); + rethrow; + } + } + + Future setExposureOffset(double offset) async { + setState(() { + _currentExposureOffset = offset; + }); + try { + offset = await controller.setExposureOffset(offset); + } on CameraException catch (e) { + _showCameraException(e); + rethrow; + } + } + + Future setFocusMode(FocusMode mode) async { + try { + await controller.setFocusMode(mode); + } on CameraException catch (e) { + _showCameraException(e); + rethrow; + } + } + + Future _startVideoPlayer() async {} + + Future takePicture() async { + if (!controller.value.isInitialized) { + developer.log('Error: select a camera first.'); + return null; + } + + if (controller.value.isTakingPicture) { + // A capture is already pending, do nothing. + return null; + } + + try { + XFile file = await controller.takePicture(); + return file; + } on CameraException catch (e) { + _showCameraException(e); + return null; + } + } + + void _showCameraException(CameraException e) { + developer.log('Error: ${e.code}\n${e.description}'); + } +} + +/// +/// Returns a suitable camera icon for [direction]. +/// +IconData getCameraLensIcon(CameraLensDirection direction) { + switch (direction) { + case CameraLensDirection.back: + return Icons.camera_rear; + case CameraLensDirection.front: + return Icons.camera_front; + case CameraLensDirection.external: + return Icons.camera; + } + throw ArgumentError('Unknown lens direction'); +} diff --git a/lib/app/pages/comment/comments_screen.dart b/lib/app/pages/comment/comments_screen.dart new file mode 100644 index 0000000..4921b3c --- /dev/null +++ b/lib/app/pages/comment/comments_screen.dart @@ -0,0 +1,151 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/app/dummy/dummy.dart'; +import 'package:flutter_new_instagram/app/pages/comment/widget/comment_widget.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class CommentsScreen extends StatefulWidget { + @override + _CommentsScreenState createState() => _CommentsScreenState(); +} + +class _CommentsScreenState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + titleSpacing: 0, + toolbarHeight: 50, + iconTheme: IconThemeData(color: Colors.black, size: 50.0), + backgroundColor: Colors.white, + title: Text('Comments', + style: TextStyle(color: Colors.black, fontSize: 18)), + elevation: 0, + actions: [ + SvgPicture.asset( + Assets.images.icSendV3, + width: 24, + height: 24, + ), + SizedBox(width: 12) + ], + ), + body: Container( + color: Colors.white, + child: ListView.separated( + physics: const BouncingScrollPhysics(), + itemCount: commentListDummy().length, + itemBuilder: (context, index) { + if (index == 0) + return Padding( + padding: const EdgeInsets.only(left: 16, top: 10, right: 20), + child: Column( + children: [ + Row( + children: [ + CircleAvatar( + radius: 15, + backgroundImage: Assets.images.imagesSample, + ), + SizedBox(width: 10), + Expanded( + child: RichText( + text: TextSpan(children: [ + TextSpan( + text: 'Hades', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + TextSpan(text: ' '), + TextSpan( + text: + 'The Maldives 🏝 are an archipelago of 1,192 islands grouped into 26 coral atolls in the Indian Ocean 🌊\nπŸŒ…πŸŒ…πŸŒ…', + style: Theme.of(context) + .textTheme + .bodyText1 + .copyWith(fontWeight: FontWeight.w400)), + ]), + ), + ), + ], + ), + SizedBox(height: 10), + Container( + width: double.infinity, + height: 0.15, + color: Colors.black, + ) + ], + ), + ); + return commentListDummy()[index]; + }, + separatorBuilder: (context, index) => SizedBox(width: 1.0), + ), + ), + bottomNavigationBar: Material( + type: MaterialType.canvas, + child: SafeArea( + child: Container( + height: 80, + margin: EdgeInsets.only( + bottom: MediaQuery.of(context).viewInsets.bottom), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + color: Colors.white, + height: 30, + child: ListView.separated( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.horizontal, + itemCount: emojiListDummy().length, + itemBuilder: (context, index) { + return emojiListDummy()[index]; + }, + separatorBuilder: (context, index) => SizedBox(width: 20), + ), + ), + Container( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Row( + children: [ + CircleAvatar( + radius: 16, + backgroundImage: Assets.images.imagesSample), + Expanded( + child: Padding( + padding: EdgeInsets.only(left: 16, right: 8), + child: TextField( + decoration: InputDecoration( + hintText: 'Comment as Hades...', + border: InputBorder.none), + ), + ), + ), + InkWell( + onTap: () {}, + child: Container( + padding: + EdgeInsets.symmetric(vertical: 8, horizontal: 8), + child: Text( + 'Post', + style: Theme.of(context) + .primaryTextTheme + .bodyText2 + .copyWith(color: Colors.blue), + ), + ), + ) + ], + ), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/app/pages/comment/widget/comment_widget.dart b/lib/app/pages/comment/widget/comment_widget.dart new file mode 100644 index 0000000..305dfa6 --- /dev/null +++ b/lib/app/pages/comment/widget/comment_widget.dart @@ -0,0 +1,77 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; + +class CommentWidget extends StatelessWidget { + final String sender; + final String message; + + const CommentWidget({Key key, this.sender, this.message}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + CircleAvatar( + radius: 15, + backgroundImage: Assets.images.imagesSample2, + ), + Expanded( + child: Container( + child: Padding( + padding: EdgeInsets.only(left: 16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RichText( + text: TextSpan(children: [ + TextSpan( + text: sender, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w600)), + TextSpan( + text: message, + style: Theme.of(context) + .textTheme + .bodyText1 + .copyWith(fontWeight: FontWeight.w400)), + ]), + ), + Padding( + padding: EdgeInsets.only(top: 4), + child: DefaultTextStyle( + style: TextStyle( + color: Colors.black54, + fontSize: 12, + fontWeight: FontWeight.w400), + child: Row( + children: [ + Text('8h'), + SizedBox(width: 24), + Text('12 likes'), + SizedBox(width: 24), + Text('Reply') + ], + )), + ) + ], + ), + ), + )), + Container( + padding: EdgeInsets.all(8), + child: Icon( + Icons.favorite_border, + size: 16, + ), + ) + ], + ), + ); + } +} diff --git a/lib/app/pages/container/home_container_screen.dart b/lib/app/pages/container/home_container_screen.dart new file mode 100644 index 0000000..30b15ec --- /dev/null +++ b/lib/app/pages/container/home_container_screen.dart @@ -0,0 +1,110 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_new_instagram/app/pages/activity/activity_screen.dart'; +import 'package:flutter_new_instagram/app/pages/explore/explore_screen.dart'; +import 'package:flutter_new_instagram/app/pages/home/home_screen.dart'; +import 'package:flutter_new_instagram/app/pages/message/message_screen.dart'; +import 'package:flutter_new_instagram/app/pages/post/post_screen.dart'; +import 'package:flutter_new_instagram/app/pages/profile/profile_screen.dart'; +import 'package:flutter_new_instagram/app/widgets/insta_bottom_nav_item.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; +import 'package:tuple/tuple.dart'; + +class HomeContainerScreen extends StatefulWidget { + @override + _HomeContainerScreenState createState() => _HomeContainerScreenState(); +} + +class _HomeContainerScreenState extends State { + PageController _pageController = PageController(initialPage: 0); + int _selectedIndex = 0; + + List> tabsIcons = [ + Tuple2(Assets.images.icHome, Assets.images.icHomeSelected), + Tuple2(Assets.images.icSearch, Assets.images.icSearchSelected), + Tuple2(Assets.images.icCreatePost, Assets.images.icCreatePost), + Tuple2(Assets.images.icFavorite, Assets.images.icFavoriteSelected), + Tuple2(null, null), + ]; + + @override + Widget build(BuildContext context) { + return Scaffold( + body: PageView( + physics: NeverScrollableScrollPhysics(), + controller: _pageController, + onPageChanged: (index) { + setState(() { + _selectedIndex = index; + }); + }, + children: [ + HomeScreen(), + ExploreScreen(), + PostScreen(), + ActivityScreen(), + ProfileScreen() + ], + ), + bottomNavigationBar: Material( + elevation: 4, + child: SafeArea( + child: Container( + decoration: BoxDecoration( + border: Border(top: Divider.createBorderSide(context))), + height: 50, + child: Row( + children: [ + Expanded( + child: InstaBottomNavItem(tabsIcons[0], 0 == _selectedIndex, + onPress: () { + setState(() { + _selectedIndex = 0; + _pageController.jumpToPage(0); + }); + })), + Expanded( + child: InstaBottomNavItem(tabsIcons[1], 1 == _selectedIndex, + onPress: () { + setState(() { + _selectedIndex = 1; + _pageController.jumpToPage(1); + }); + }), + ), + Expanded( + child: InstaBottomNavItem(tabsIcons[2], 2 == _selectedIndex, + onPress: () { + _selectedIndex = 2; + _pageController.jumpToPage(2); + })), + Expanded( + child: InstaBottomNavItem(tabsIcons[3], 3 == _selectedIndex, + onPress: () { + setState(() { + _selectedIndex = 3; + _pageController.jumpToPage(3); + }); + })), + Expanded( + child: InstaBottomNavItem(tabsIcons[4], 4 == _selectedIndex, + onPress: () { + setState(() { + _selectedIndex = 4; + _pageController.jumpToPage(4); + }); + })), + ], + ), + ), + ), + ), + ); + } + + void _onItemTapped(int index) { + setState(() { + _selectedIndex = index; + }); + } +} diff --git a/lib/app/pages/explore/explore_screen.dart b/lib/app/pages/explore/explore_screen.dart new file mode 100644 index 0000000..e07c4b7 --- /dev/null +++ b/lib/app/pages/explore/explore_screen.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/app/pages/explore/widgets/explore_item_widget.dart'; +import 'package:flutter_new_instagram/app/pages/explore/widgets/search_category_widget.dart'; +import 'package:flutter_new_instagram/app/pages/explore/widgets/search_widget.dart'; +import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; + +class ExploreScreen extends StatefulWidget { + @override + _ExploreScreenState createState() => _ExploreScreenState(); +} + +class _ExploreScreenState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white70, + body: Padding( + padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top), + child: CustomScrollView( + slivers: [ + SliverPersistentHeader( + pinned: false, + // Allows the user to reveal the app bar if they + // begin scrolling back up the list of items. + floating: true, + delegate: SliverSearchDelegateWidget(), + ), + SliverPersistentHeader( + pinned: true, + floating: false, + delegate: SliverSearchCategoryWidget(), + ), + SliverStaggeredGrid.countBuilder( + itemCount: 30, + crossAxisCount: 3, + mainAxisSpacing: 2, + crossAxisSpacing: 2, + itemBuilder: (BuildContext context, int index) { + return _exploreList()[index % 10]; + }, + staggeredTileBuilder: (int index) { + return StaggeredTile.count( + index % 5 == 0 ? 2 : 1, index % 5 == 0 ? 2 : 1); + }, + ), + ], + ), + ), + ); + } + + List _exploreList() { + return [ + ExploreItemWidget( + 'https://wallpapercave.com/wp/wp3156022.jpg', ExploreType.VIDEO), + ExploreItemWidget('https://wallpapercave.com/uwp/uwp9990.png', + ExploreType.SINGLE_IMAGE), + ExploreItemWidget('https://wallpapercave.com/wp/wp3856709.jpg', + ExploreType.MULTI_IMAGE), + ExploreItemWidget('https://wallpapercave.com/wp/wp7804681.jpg', + ExploreType.SINGLE_IMAGE), + ExploreItemWidget('https://wallpapercave.com/wp/wp3856716.png', + ExploreType.MULTI_IMAGE), + ExploreItemWidget( + 'https://wallpapercave.com/wp/wp5376668.png', ExploreType.VIDEO), + ExploreItemWidget('https://wallpapercave.com/wp/wp7804706.jpg', + ExploreType.MULTI_IMAGE), + ExploreItemWidget('https://wallpapercave.com/wp/wp2471312.jpg', + ExploreType.SINGLE_IMAGE), + ExploreItemWidget('https://wallpapercave.com/wp/wp6363703.png', + ExploreType.MULTI_IMAGE), + ExploreItemWidget('https://wallpapercave.com/uwp/uwp131677.jpeg', + ExploreType.SINGLE_IMAGE), + ]; + } +} diff --git a/lib/app/pages/explore/widgets/explore_item_widget.dart b/lib/app/pages/explore/widgets/explore_item_widget.dart new file mode 100644 index 0000000..26c9659 --- /dev/null +++ b/lib/app/pages/explore/widgets/explore_item_widget.dart @@ -0,0 +1,48 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +enum ExploreType { + SINGLE_IMAGE, + MULTI_IMAGE, + VIDEO, +} + +class ExploreItemWidget extends StatelessWidget { + final String thumbnailUrl; + final ExploreType type; + + const ExploreItemWidget(this.thumbnailUrl, this.type); + + @override + Widget build(BuildContext context) { + return Container( + child: Stack( + children: [ + AspectRatio( + aspectRatio: 1, + child: CachedNetworkImage( + imageUrl: thumbnailUrl, fit: BoxFit.cover)), + Container( + alignment: Alignment.topRight, + padding: EdgeInsets.all(4.0), + child: _exploreItem(), + ) + ], + ), + ); + } + + Widget _exploreItem() { + if (type == ExploreType.MULTI_IMAGE) { + return SvgPicture.asset(Assets.images.icMulti, + width: 20, height: 20, color: Colors.white); + } else if (type == ExploreType.VIDEO) { + return SvgPicture.asset(Assets.images.icPlay, + width: 20, height: 20, color: Colors.white); + } else { + return SizedBox(); + } + } +} diff --git a/lib/app/pages/explore/widgets/search_category_widget.dart b/lib/app/pages/explore/widgets/search_category_widget.dart new file mode 100644 index 0000000..c56411f --- /dev/null +++ b/lib/app/pages/explore/widgets/search_category_widget.dart @@ -0,0 +1,81 @@ +import 'package:flutter/material.dart'; + +class SliverSearchCategoryWidget extends SliverPersistentHeaderDelegate { + List categories = [ + 'IGTV', + 'TV & Movies', + 'Travel', + 'Architecture', + 'Beauty', + 'Art', + 'Decor', + 'Style', + 'Food', + 'DIY', + 'Music', + 'Sports' + ]; + + @override + Widget build( + BuildContext context, double shrinkOffset, bool overlapsContent) { + return Container( + height: 46, + color: Colors.white, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: ListView.separated( + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.horizontal, + itemCount: categories.length, + itemBuilder: (context, index) { + return Container( + child: index == 0 + ? Padding( + padding: const EdgeInsets.only(left: 10), + child: SearchCategoryWidget(categories[index])) + : SearchCategoryWidget(categories[index]), + ); + }, + separatorBuilder: (context, index) => SizedBox(width: 6)), + ), + ); + } + + @override + double get maxExtent => 46; + + @override + double get minExtent => 46; + + @override + bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) { + return true; + } +} + +class SearchCategoryWidget extends StatelessWidget { + final String category; + + const SearchCategoryWidget(this.category); + + @override + Widget build(BuildContext context) { + return Container( + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: Colors.grey[400], + width: 1, + ), + color: Colors.transparent), + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 2.0), + child: Text( + category, + style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500), + )), + ); + } +} diff --git a/lib/app/pages/explore/widgets/search_widget.dart b/lib/app/pages/explore/widgets/search_widget.dart new file mode 100644 index 0000000..f9fa662 --- /dev/null +++ b/lib/app/pages/explore/widgets/search_widget.dart @@ -0,0 +1,97 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class SliverSearchDelegateWidget extends SliverPersistentHeaderDelegate { + @override + Widget build( + BuildContext context, double shrinkOffset, bool overlapsContent) { + return Container( + color: Colors.white, + child: Padding( + padding: const EdgeInsets.all(10.0).copyWith(bottom: 0), + child: Row( + children: [ + Expanded( + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: Colors.grey[200]), + child: ExploreSearchWidget()), + ), + Padding( + padding: const EdgeInsets.only(left: 16), + child: SvgPicture.asset(Assets.images.icFilterCrop, + width: 30, height: 30), + ) + ], + ), + ), + ); + } + + @override + double get maxExtent => 50; + + @override + double get minExtent => 50; + + @override + bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) { + return true; + } +} + +class ExploreSearchWidget extends StatefulWidget { + @override + _ExploreSearchWidgetState createState() => _ExploreSearchWidgetState(); +} + +class _ExploreSearchWidgetState extends State { + TextEditingController _editingController; + + @override + void initState() { + super.initState(); + _editingController = TextEditingController(); + } + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(left: 16), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: TextField( + controller: _editingController, + onChanged: (_) => setState(() {}), + decoration: InputDecoration( + hintText: 'Search', + hintStyle: TextStyle(color: Colors.grey.withOpacity(0.5)), + enabledBorder: InputBorder.none, + focusedBorder: InputBorder.none, + ), + ), + ), + _editingController.text.trim().isEmpty + ? IconButton( + icon: Icon(Icons.search, color: Colors.grey.withOpacity(0.8)), + onPressed: null) + : IconButton( + highlightColor: Colors.transparent, + splashColor: Colors.transparent, + icon: Icon(Icons.clear, color: Colors.grey.withOpacity(0.8)), + onPressed: () => setState( + () { + _editingController.clear(); + }, + ), + ), + ], + ), + ); + } +} diff --git a/lib/app/pages/home/home_screen.dart b/lib/app/pages/home/home_screen.dart new file mode 100644 index 0000000..b40a88e --- /dev/null +++ b/lib/app/pages/home/home_screen.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/app/pages/home/widget/feed_widget.dart'; +import 'package:flutter_new_instagram/app/pages/home/widget/home_appbar_widget.dart'; +import 'package:flutter_new_instagram/app/pages/home/widget/home_story_item_widget.dart'; +import 'package:flutter_new_instagram/app/pages/home/widget/self_story_item_widget.dart'; +import 'package:liquid_pull_to_refresh/liquid_pull_to_refresh.dart'; + +class HomeScreen extends StatefulWidget { + @override + _HomeScreenState createState() => _HomeScreenState(); +} + +class _HomeScreenState extends State { + @override + Widget build(BuildContext context) { + return SafeArea( + child: Scaffold( + appBar: HomeAppBarWidget(), + body: LiquidPullToRefresh( + onRefresh: () async { + await Future.delayed(Duration(seconds: 1)); + }, + color: Colors.white, + height: 60, + borderWidth: 2, + backgroundColor: Colors.orange, + springAnimationDurationInMilliseconds: 200, + showChildOpacityTransition: false, + child: Container( + color: Colors.white, + child: ListView.builder( + physics: BouncingScrollPhysics(), + itemCount: 20, + itemBuilder: (context, index) { + return index == 0 ? _buildInstaStories() : FeedWidget(); + }, + ), + ), + ), + ), + ); + } + + Widget _buildInstaStories() { + // Max item shown in list = 5 + final itemWidth = (MediaQuery.of(context).size.width - 12.0 * 5) / 5.5; + + return Column( + children: [ + Container( + height: itemWidth + 40, + child: ListView.separated( + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.horizontal, + itemCount: 10, + itemBuilder: (context, index) { + return Container( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4.0, vertical: 8.0), + child: index == 0 + ? SelfStoryItemWidget(size: itemWidth) + : HomeStoryItemWidget(size: itemWidth))); + }, + separatorBuilder: (context, index) => SizedBox(width: 1.0), + ), + ), + const Divider( + color: Colors.black12, + height: 1, + thickness: 0.5, + ) + ], + ); + } +} diff --git a/lib/app/pages/home/widget/feed_widget.dart b/lib/app/pages/home/widget/feed_widget.dart new file mode 100644 index 0000000..efb41c4 --- /dev/null +++ b/lib/app/pages/home/widget/feed_widget.dart @@ -0,0 +1,212 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/app/pages/comment/comments_screen.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; + +class FeedWidget extends StatefulWidget { + @override + _FeedWidgetState createState() => _FeedWidgetState(); +} + +class _FeedWidgetState extends State { + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildHeader(), + _buildContent(), + _buildActions(), + _buildFooter() + ], + ); + } + + Widget _buildActions() { + return Padding( + padding: const EdgeInsets.only(top: 10, left: 2), + child: Row( + children: [ + InkResponse( + onTap: () {}, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: SvgPicture.asset(Assets.images.icHeartOutline, + width: 22, height: 22, color: Colors.black), + ), + ), + InkResponse( + onTap: () {}, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: SvgPicture.asset(Assets.images.icCommentV3, + width: 22, height: 22, color: Colors.black), + ), + ), + InkResponse( + onTap: () {}, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: SvgPicture.asset(Assets.images.icSendV3, + width: 22, height: 22, color: Colors.black), + ), + ), + Spacer(), + InkResponse( + onTap: () {}, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: SvgPicture.asset(Assets.images.icBookmark, + width: 22, height: 22, color: Colors.black), + ), + ), + ], + ), + ); + } + + Widget _buildFooter() { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '666,888 likes', + textAlign: TextAlign.start, + style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold), + ), + SizedBox(height: 4.0), + RichText( + text: TextSpan(children: [ + TextSpan( + text: 'Hades', + style: TextStyle( + color: Colors.black, fontWeight: FontWeight.bold)), + TextSpan(text: ' '), + TextSpan( + text: + 'The Maldives 🏝 are an archipelago of 1,192 islands grouped into 26 coral atolls in the Indian Ocean 🌊\nπŸŒ…πŸŒ…πŸŒ…', + style: Theme.of(context) + .textTheme + .bodyText1 + .copyWith(fontWeight: FontWeight.w400)), + ]), + ), + InkWell( + child: Container( + child: Text( + 'View all 238 comments', + style: Theme.of(context) + .textTheme + .caption + .copyWith(fontSize: 13.5), + ), + padding: EdgeInsets.symmetric(vertical: 4), + ), + onTap: () { + Get.to(CommentsScreen()); + }, + ), + Text( + '7 days ago', + style: Theme.of(context).textTheme.caption.copyWith(fontSize: 10), + ), + ], + ), + ); + } + + Widget _buildContent() { + return Container( + child: AspectRatio( + aspectRatio: 16 / 10, + child: CachedNetworkImage( + imageUrl: 'https://wallpapercave.com/uwp/uwp556880.jpeg', + fit: BoxFit.fill, + ), + ), + ); + } + + Widget _buildHeader() { + return Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CircleAvatar( + radius: 16, + backgroundImage: + NetworkImage('https://i.ibb.co/3dhG6cS/kim-joo-jung.jpg')), + Expanded( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text('Hades', + style: TextStyle( + color: Colors.black87, + fontWeight: FontWeight.w600, + fontSize: 14.0)), + Text(' β€’ '), + Text( + 'Follow', + style: TextStyle( + color: Colors.blue, + fontSize: 13.5, + fontWeight: FontWeight.w600), + ) + ], + ), + SizedBox(height: 2), + Text( + 'San Antonio, Texas', + style: TextStyle( + color: Colors.black, + fontSize: 10.0, + fontWeight: FontWeight.w300), + ) + ], + ), + )), + IconButton( + icon: Icon(Icons.more_vert), + onPressed: () { + showDialog( + context: context, + child: Dialog( + child: ListView( + padding: EdgeInsets.symmetric(vertical: 16), + shrinkWrap: true, + children: [ + 'Report...', + 'Turn on Post notifications', + 'Copy Link', + 'Share to...', + 'Mute' + ] + .map((e) => InkWell( + child: Container( + padding: EdgeInsets.symmetric( + vertical: 12, horizontal: 16), + child: Text(e), + ), + onTap: () { + Navigator.pop(context); + }, + )) + .toList()), + )); + }) + ], + ), + ); + } +} diff --git a/lib/app/pages/home/widget/home_appbar_widget.dart b/lib/app/pages/home/widget/home_appbar_widget.dart new file mode 100644 index 0000000..36e0c1f --- /dev/null +++ b/lib/app/pages/home/widget/home_appbar_widget.dart @@ -0,0 +1,48 @@ +import 'package:camera/camera.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/app/pages/camera/camera_screen.dart'; +import 'package:flutter_new_instagram/app/pages/message/message_screen.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; + +class HomeAppBarWidget extends StatelessWidget with PreferredSizeWidget { + const HomeAppBarWidget(); + + @override + Widget build(BuildContext context) { + return Material( + color: Colors.white, + elevation: 1, + child: Row( + children: [ + IconButton( + icon: SvgPicture.asset( + Assets.images.icCameraV2, + color: Colors.black, + width: 24, + height: 24, + ), + onPressed: () async { + List cameras = []; + cameras = await availableCameras(); + Get.to(CameraScreen(cameras)); + }), + Expanded( + child: Container( + child: SvgPicture.asset(Assets.images.logoInsta), + )), + IconButton( + icon: SvgPicture.asset(Assets.images.icMesenger, + width: 25, + height: 25, + color: Colors.black), + onPressed: () => Get.to(MessageScreen())) + ], + ), + ); + } + + @override + Size get preferredSize => Size.fromHeight(400); +} diff --git a/lib/app/pages/home/widget/home_story_item_widget.dart b/lib/app/pages/home/widget/home_story_item_widget.dart new file mode 100644 index 0000000..66415ad --- /dev/null +++ b/lib/app/pages/home/widget/home_story_item_widget.dart @@ -0,0 +1,66 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; + +class HomeStoryItemWidget extends StatelessWidget { + final VoidCallback onItemPress; + final double size; + + const HomeStoryItemWidget({this.onItemPress, this.size}); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () => onItemPress, + splashColor: Colors.transparent, + highlightColor: Colors.transparent, + child: Column( + children: [ + Container( + width: size, + height: size, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(size / 2.0), + gradient: SweepGradient(colors: [ + Color.fromARGB(255, 193, 53, 132), + Color.fromARGB(255, 245, 96, 64), + Color.fromARGB(255, 252, 175, 69), + Color.fromARGB(255, 245, 96, 64), + Color.fromARGB(255, 193, 53, 132), + ]), + ), + child: Padding( + padding: const EdgeInsets.all(2), + child: ClipRRect( + borderRadius: BorderRadius.circular(size / 2.0), + child: Container( + child: CachedNetworkImage( + placeholder: (context, url) => Container( + decoration: ShapeDecoration( + color: Colors.white, shape: CircleBorder()), + ), + imageUrl: 'https://i.ibb.co/TbP0qWJ/iuiuiuiuiu.jpg', + fit: BoxFit.fill, + ))), + ), + ), + ), + Container( + width: size, + alignment: Alignment.center, + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 2.0, vertical: 4.0), + child: Text( + 'Hades', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle(color: Colors.black, fontSize: 10.0), + ), + ), + ) + ], + ), + ); + } +} diff --git a/lib/app/pages/home/widget/self_story_item_widget.dart b/lib/app/pages/home/widget/self_story_item_widget.dart new file mode 100644 index 0000000..aa51238 --- /dev/null +++ b/lib/app/pages/home/widget/self_story_item_widget.dart @@ -0,0 +1,89 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; + +class SelfStoryItemWidget extends StatelessWidget { + final VoidCallback onItemPress; + final double size; + + const SelfStoryItemWidget({this.onItemPress, this.size}); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () => onItemPress, + splashColor: Colors.transparent, + highlightColor: Colors.transparent, + child: Column( + children: [ + Stack( + children: [ + Container( + width: size, + height: size, + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Colors.white30, + spreadRadius: 0, + blurRadius: 4, + offset: Offset(0, 4), + ) + ], + borderRadius: BorderRadius.circular(size / 2.0), + color: Colors.transparent, + border: Border.all( + color: Colors.white30, + width: 3, + ), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(size / 2.0), + child: Padding( + padding: const EdgeInsets.all(0.0), + child: Center( + child: CachedNetworkImage( + fit: BoxFit.fill, + imageUrl: + 'https://i.ibb.co/3dhG6cS/kim-joo-jung.jpg'), + ), + ), + ), + ), + Container( + width: size, + height: size, + alignment: Alignment.bottomRight, + child: Container( + decoration: ShapeDecoration( + color: Colors.white, shape: CircleBorder()), + child: Icon( + Icons.add_circle_outlined, + color: Colors.blue, + size: 20, + ), + ), + ) + ], + ), + Container( + width: size, + alignment: Alignment.center, + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 2.0, vertical: 4.0), + child: Text( + 'Your story', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Colors.black, + fontSize: 10.0, + fontWeight: FontWeight.bold), + ), + ), + ) + ], + ), + ); + } +} diff --git a/lib/app/pages/login/sign_in_screen.dart b/lib/app/pages/login/sign_in_screen.dart new file mode 100644 index 0000000..7c41ed0 --- /dev/null +++ b/lib/app/pages/login/sign_in_screen.dart @@ -0,0 +1,194 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/app/pages/main_screen.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; + +class SignInScreen extends StatefulWidget { + @override + _SignInScreenState createState() => _SignInScreenState(); +} + +class _SignInScreenState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.bottomLeft, + end: Alignment.topRight, + colors: [ + Color.fromARGB(255, 64, 93, 230), + Color.fromARGB(255, 131, 58, 180), + Color.fromARGB(255, 193, 53, 132), + ])), + child: Column( + children: [ + Expanded( + child: Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + Assets.images.icInstagram, + fit: BoxFit.fill, + color: Colors.white, + ), + Padding( + padding: + const EdgeInsets.only(top: 16.0, left: 40, right: 40), + child: Text( + 'Sign up to see photos & videos from your friends', + style: Theme.of(context) + .textTheme + .caption + .copyWith(color: Colors.white, fontSize: 17), + textAlign: TextAlign.center), + ), + ], + )), + flex: 4), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + TextFormField( + decoration: InputDecoration( + hintText: 'Email or username', + fillColor: Colors.white, + border: OutlineInputBorder( + borderSide: Divider.createBorderSide(context)), + focusedBorder: OutlineInputBorder( + borderSide: Divider.createBorderSide(context)), + enabledBorder: OutlineInputBorder( + borderSide: Divider.createBorderSide(context)), + filled: true, + contentPadding: EdgeInsets.all(8), + ), + ), + SizedBox(height: 14.0), + TextFormField( + decoration: InputDecoration( + hintText: 'Password', + fillColor: Colors.white, + border: OutlineInputBorder( + borderSide: Divider.createBorderSide(context)), + focusedBorder: OutlineInputBorder( + borderSide: Divider.createBorderSide(context)), + enabledBorder: OutlineInputBorder( + borderSide: Divider.createBorderSide(context)), + filled: true, + contentPadding: EdgeInsets.all(8), + ), + ), + SizedBox(height: 14.0), + RaisedButton( + padding: const EdgeInsets.all(14.0), + textColor: Colors.white, + color: Colors.blue, + onPressed: () => {Get.to(MainScreen())}, + child: Text( + "Log In", + style: TextStyle(color: Colors.white, fontSize: 15.0), + ), + ), + SizedBox(height: 14.0), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('Forgot your login details? ', + style: TextStyle(color: Colors.black54)), + Text( + 'Get help logging in.', + style: TextStyle( + color: Colors.black54, + fontWeight: FontWeight.bold), + ) + ], + ), + SizedBox(height: 14.0), + Row( + children: [ + Spacer(flex: 1), + Expanded( + child: Container( + height: 0.5, + color: Colors.grey, + ), + flex: 2), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 8.0), + child: Text('OR', + style: TextStyle(color: Colors.white70)), + ), + Expanded( + child: Container( + height: 0.5, + color: Colors.grey, + ), + flex: 2), + Spacer(flex: 1), + ], + ), + SizedBox(height: 10.0), + RaisedButton( + padding: const EdgeInsets.all(14.0), + textColor: Colors.white, + color: Colors.blue, + onPressed: () => {}, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + Assets.images.icFacebook, + color: Colors.white, + width: 20, + height: 20, + ), + SizedBox(width: 10), + Text("Log in as @Hades") + ], + ), + ), + ], + ), + ), + flex: 6), + Container( + color: Colors.white10, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + color: Colors.white24, + height: 0.5, + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 16), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text("Don't have an account? ", + style: TextStyle(color: Colors.black54)), + Text( + 'Sign up.', + style: TextStyle( + color: Colors.white54, + fontWeight: FontWeight.bold), + ) + ], + ), + ), + ], + ), + ) + ], + ), + ), + ); + } +} diff --git a/lib/app/pages/main_screen.dart b/lib/app/pages/main_screen.dart new file mode 100644 index 0000000..da355e3 --- /dev/null +++ b/lib/app/pages/main_screen.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/app/pages/camera/camera_screen.dart'; +import 'package:flutter_new_instagram/app/pages/container/home_container_screen.dart'; +import 'package:flutter_new_instagram/app/pages/message/message_screen.dart'; + +class MainScreen extends StatefulWidget { + @override + _MainScreenState createState() => _MainScreenState(); +} + +class _MainScreenState extends State { + PageController _pageController = PageController(initialPage: 1); + int currentIndex = 1; + + @override + Widget build(BuildContext context) { + return WillPopScope( + child: PageView( + controller: _pageController, + onPageChanged: (index) { + currentIndex = index; + }, + children: [CameraScreen([]), HomeContainerScreen(), MessageScreen()], + ), + onWillPop: () async { + if (currentIndex == 0) { + _pageController.animateToPage(1, + duration: Duration(milliseconds: 300), curve: Curves.easeIn); + return false; + } + return true; + }, + ); + } +} diff --git a/lib/app/pages/message/message_screen.dart b/lib/app/pages/message/message_screen.dart new file mode 100644 index 0000000..86d05d7 --- /dev/null +++ b/lib/app/pages/message/message_screen.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; + +class MessageScreen extends StatefulWidget { + @override + _MessageScreenState createState() => _MessageScreenState(); +} + +class _MessageScreenState extends State { + @override + Widget build(BuildContext context) { + return Container( + color: Colors.blue, + ); + } +} diff --git a/lib/app/pages/post/confirm/confirm_new_post_screen.dart b/lib/app/pages/post/confirm/confirm_new_post_screen.dart new file mode 100644 index 0000000..bb27d24 --- /dev/null +++ b/lib/app/pages/post/confirm/confirm_new_post_screen.dart @@ -0,0 +1,138 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/app/dummy/dummy.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; +import 'package:flutter_svg/svg.dart'; + +class ConfirmNewPostScreen extends StatefulWidget { + @override + _ConfirmNewPostScreenState createState() => _ConfirmNewPostScreenState(); +} + +class _ConfirmNewPostScreenState extends State { + var _toggled = false; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + titleSpacing: 0, + toolbarHeight: 50, + iconTheme: IconThemeData(color: Colors.black, size: 50.0), + backgroundColor: Colors.white, + title: Text('New Post', + style: TextStyle(color: Colors.black, fontSize: 18)), + elevation: 0, + actions: [ + IconButton( + icon: Icon(Icons.check), + color: Colors.blue, + onPressed: () {}, + ) + ], + ), + body: Container( + color: Colors.white, + height: double.infinity, + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildNewPostHeaderItem(), + _buildDivider(), + ListTile(dense: true, leading: Text('Tag People')), + _buildDivider(), + ListTile(dense: true, leading: Text('Add Location')), + _buildDivider(), + _buildSuggestLocations(), + _buildDivider(), + ListTile( + dense: true, + leading: Text( + 'Also post to', + style: TextStyle(fontSize: 15), + )), + ListTile( + dense: true, + leading: Text('Facebook'), + title: Container( + alignment: Alignment.centerRight, + child: Text('Trung Huong'), + ), + trailing: Switch( + value: _toggled, + activeColor: Colors.lightBlue, + activeTrackColor: Colors.lightBlueAccent, + onChanged: (bool value) { + setState(() { + _toggled = !_toggled; + }); + }), + ), + ListTile( + dense: true, + leading: Text('Twitter'), + trailing: Switch(value: false, onChanged: null)), + ListTile( + dense: true, + leading: Text('Tumblr'), + trailing: Switch(value: false, onChanged: null), + ) + ], + ), + ), + ), + ); + } + + Widget _buildSuggestLocations() { + return Container( + height: 50, + child: ListView.separated( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.horizontal, + itemCount: locationListSuggest().length, + itemBuilder: (context, index) { + return locationListSuggest()[index]; + }, + separatorBuilder: (context, index) => SizedBox(width: 10), + ), + ); + } + + Widget _buildDivider() { + return Container( + width: double.infinity, + height: 0.1, + color: Colors.black, + ); + } + + Widget _buildNewPostHeaderItem() { + return Container( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + CircleAvatar(radius: 16, backgroundImage: Assets.images.imagesSample), + Expanded( + child: Padding( + padding: EdgeInsets.only(left: 16, right: 8), + child: TextField( + decoration: InputDecoration( + hintText: 'Write a caption...', border: InputBorder.none), + ), + ), + ), + Container( + width: 68, + height: 68, + child: ClipRRect( + borderRadius: BorderRadius.circular(2), + child: Image.asset(Assets.images.imagesSample2.assetName, + fit: BoxFit.cover)), + ), + ], + ), + ); + } +} diff --git a/lib/app/pages/post/post_screen.dart b/lib/app/pages/post/post_screen.dart new file mode 100644 index 0000000..1c8ee18 --- /dev/null +++ b/lib/app/pages/post/post_screen.dart @@ -0,0 +1,134 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/app/pages/post/confirm/confirm_new_post_screen.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; +import 'package:get/get.dart'; + +class PostScreen extends StatefulWidget { + @override + _PostScreenState createState() => _PostScreenState(); +} + +class _PostScreenState extends State { + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top), + child: Scaffold( + appBar: PreferredSize( + preferredSize: Size.fromHeight(22), + child: Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + IconButton( + icon: Icon(Icons.close, color: Colors.black), + onPressed: () {}, + ), + Spacer(), + InkResponse( + child: Text( + 'Next', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w500, + fontSize: 16), + ), + onTap: () => Get.to(ConfirmNewPostScreen())), + SizedBox(width: 12) + ], + )), + ), + body: Column( + children: [ + AspectRatio( + aspectRatio: 1, + child: Container( + child: Stack( + children: [ + Positioned.fill( + child: Image.asset( + Assets.images.imagesSample2.assetName, + fit: BoxFit.cover, + ), + ), + Positioned( + child: Container( + padding: EdgeInsets.all(8), + child: Row( + children: [ + Container( + child: IconButton( + icon: Icon( + Icons.zoom_out_map, + size: 16, + color: Colors.white, + ), + onPressed: () {}), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.black54)), + Expanded(child: Container()), + Container( + child: IconButton( + icon: Icon(Icons.camera, + size: 16, color: Colors.white), + onPressed: () {}), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.black54)), + SizedBox( + width: 16, + ), + Container( + child: IconButton( + icon: Icon(Icons.format_shapes, + size: 16, color: Colors.white), + onPressed: () {}), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.black54)), + SizedBox( + width: 16, + ), + Container( + child: IconButton( + icon: Icon(Icons.content_copy, + size: 16, color: Colors.white), + onPressed: () {}), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.black54)) + ], + ), + ), + bottom: 0, + left: 0, + right: 0, + ) + ], + ), + ), + ), + Expanded( + child: GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 4, + crossAxisSpacing: 2, + mainAxisSpacing: 2), + itemCount: 15, + itemBuilder: (context, index) { + return InkResponse( + child: Image.asset( + Assets.images.imagesSample.assetName, + fit: BoxFit.cover, + ), + onTap: () {}, + ); + })) + ], + ), + ), + ); + } +} diff --git a/lib/app/pages/profile/profile_screen.dart b/lib/app/pages/profile/profile_screen.dart new file mode 100644 index 0000000..01e3f4f --- /dev/null +++ b/lib/app/pages/profile/profile_screen.dart @@ -0,0 +1,141 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/app/dummy/dummy.dart'; +import 'package:flutter_new_instagram/app/pages/profile/widgets/bottom_sheet_action_widget.dart'; +import 'package:flutter_new_instagram/app/pages/profile/widgets/profile_app_bar_widget.dart'; +import 'package:flutter_new_instagram/app/pages/profile/widgets/profile_header_info_widget.dart'; +import 'package:flutter_new_instagram/app/pages/profile/widgets/profile_highlights_widget.dart'; +import 'package:flutter_new_instagram/app/pages/profile/widgets/profile_sliver_tabbar_delegate.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:tuple/tuple.dart'; + +class ProfileScreen extends StatefulWidget { + @override + _ProfileScreenState createState() => _ProfileScreenState(); +} + +class _ProfileScreenState extends State { + @override + Widget build(BuildContext context) { + return DefaultTabController( + length: 2, + child: Scaffold( + body: SafeArea( + child: NestedScrollView( + headerSliverBuilder: (context, bodyIsScrolled) { + return [ + ProfileAppBarWidget(onShowMenu: () => _onShowMenu(context)), + SliverToBoxAdapter(child: ProfileHeaderInfoWidget()), + SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: ProfileHighlightsWidget(), + )), + SliverPersistentHeader( + pinned: true, + delegate: ProfileSliverPersistentHeaderTabBar( + child: Container( + color: Colors.white, + height: 50, + child: TabBar( + indicatorColor: Colors.orange, + tabs: [ + Tab( + icon: Icon( + Icons.grid_on, + color: Colors.black, + )), + Tab( + icon: Icon(Icons.person_outline, + color: Colors.black)) + ], + ), + ))) + ]; + }, + body: TabBarView(children: [ + GridView.builder( + padding: EdgeInsets.all(2), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + crossAxisSpacing: 2, + mainAxisSpacing: 2), + itemCount: 40, + itemBuilder: (context, index) { + return exploreListDummy()[index % 10]; + }), + GridView.builder( + padding: EdgeInsets.all(2), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 4, + crossAxisSpacing: 2, + mainAxisSpacing: 2), + itemCount: 40, + itemBuilder: (context, index) { + return exploreListDummy()[index % 10]; + }) + ])), + ), + ), + ); + } + + void _onShowMenu(BuildContext context) { + showModalBottomSheet( + context: context, + backgroundColor: Colors.transparent, + builder: (context) { + return Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.vertical(top: Radius.circular(16.0)), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.grey, + offset: Offset(0.0, 1.0), + blurRadius: 5.0, + ), + ], + ), + child: Container( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + width: 50, + height: 5, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: Colors.grey), + ), + ), + Text('Create New', + style: + TextStyle(fontWeight: FontWeight.bold, fontSize: 15)), + SizedBox(height: 10), + Container(height: 0.1, color: Colors.black), + ListView.builder( + shrinkWrap: true, + physics: BouncingScrollPhysics(), + itemCount: kActions.length, + itemBuilder: (context, index) { + return BottomSheetActionWidget(kActions[index], null); + }, + ), + ], + ), + ), + ); + }); + } + + List get kActions => [ + Tuple2(Assets.images.icFeedPost, 'Feed Post'), + Tuple2(Assets.images.icStory, 'Story'), + Tuple2(Assets.images.icStoryHighlight, 'Story Highlight'), + Tuple2(Assets.images.icIgtvVideo, 'IGTV Video'), + Tuple2(Assets.images.icGuide, 'Guide') + ]; +} diff --git a/lib/app/pages/profile/widgets/bottom_sheet_action_widget.dart b/lib/app/pages/profile/widgets/bottom_sheet_action_widget.dart new file mode 100644 index 0000000..96e86d3 --- /dev/null +++ b/lib/app/pages/profile/widgets/bottom_sheet_action_widget.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:tuple/tuple.dart'; + +class BottomSheetActionWidget extends StatelessWidget { + final Tuple2 action; + final Function onTap; + + BottomSheetActionWidget(this.action, this.onTap); + + @override + Widget build(BuildContext context) { + return InkWell( + child: Container( + padding: EdgeInsets.symmetric(vertical: 12, horizontal: 16), + child: Row( + children: [ + SvgPicture.asset(action.item1, width: 24,height: 24), + SizedBox( + width: 16, + ), + Text(action.item2) + ], + ), + ), + onTap: () => onTap, + ); + } +} diff --git a/lib/app/pages/profile/widgets/profile_app_bar_widget.dart b/lib/app/pages/profile/widgets/profile_app_bar_widget.dart new file mode 100644 index 0000000..4cd5914 --- /dev/null +++ b/lib/app/pages/profile/widgets/profile_app_bar_widget.dart @@ -0,0 +1,81 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class ProfileAppBarWidget extends StatefulWidget { + final Function onShowMenu; + + const ProfileAppBarWidget({Key key, this.onShowMenu}) : super(key: key); + + @override + _ProfileAppBarWidgetState createState() => _ProfileAppBarWidgetState(); +} + +class _ProfileAppBarWidgetState extends State { + @override + Widget build(BuildContext context) { + return SliverPersistentHeader( + pinned: true, delegate: ProfileAppBarDelegate(widget.onShowMenu)); + } +} + +class ProfileAppBarDelegate extends SliverPersistentHeaderDelegate { + final Function onShowMenu; + + ProfileAppBarDelegate(this.onShowMenu); + + @override + Widget build( + BuildContext context, double shrinkOffset, bool overlapsContent) { + return Padding( + padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top), + child: Container( + padding: const EdgeInsets.only(left: 16), + color: Colors.white, + // decoration: BoxDecoration(boxShadow: [ + // BoxShadow( + // color: Colors.black12, + // offset: Offset(0, 2), + // ) + // ], color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + alignment: Alignment.center, + child: Row( + children: [ + Text('Hades', + style: TextStyle( + color: Colors.black, + fontSize: 16, + fontWeight: FontWeight.bold)), + Icon(Icons.keyboard_arrow_down, size: 20), + Text('β€’', style: TextStyle(color: Colors.red, fontSize: 35)) + ], + ), + ), + Row( + children: [ + SvgPicture.asset(Assets.images.icProfileAdd, + width: 20, height: 20), + IconButton(icon: Icon(Icons.menu), onPressed: onShowMenu), + ], + ) + ], + ), + ), + ); + } + + @override + double get maxExtent => 50; + + @override + double get minExtent => 50; + + @override + bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) { + return true; + } +} diff --git a/lib/app/pages/profile/widgets/profile_header_info_widget.dart b/lib/app/pages/profile/widgets/profile_header_info_widget.dart new file mode 100644 index 0000000..ef16ebe --- /dev/null +++ b/lib/app/pages/profile/widgets/profile_header_info_widget.dart @@ -0,0 +1,112 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; + +class ProfileHeaderInfoWidget extends StatefulWidget { + @override + _ProfileHeaderInfoWidgetState createState() => + _ProfileHeaderInfoWidgetState(); +} + +class _ProfileHeaderInfoWidgetState extends State { + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6) + .copyWith(bottom: 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + CircleAvatar( + radius: 35, + backgroundImage: Assets.images.imagesSample, + ), + Expanded(child: _buildItem('Posts', '9,999')), + Expanded(child: _buildItem('Followers', '6,818')), + Expanded(child: _buildItem('Followings', '123')), + ], + ), + Padding( + padding: EdgeInsets.only(top: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Pham Trung Huong', + style: TextStyle(fontWeight: FontWeight.bold, height: 1.5), + ), + SizedBox(height: 15), + Text( + 'πŸ†ƒπŸ…·πŸ…ΈπŸ…½πŸ…Ί πŸ…±πŸ…ΈπŸ…Ά 🏝', + style: TextStyle(fontWeight: FontWeight.w100), + ), + Text( + 'You can\'t start the next chapter of your life \nif you keep re-reading the last one πŸ”₯πŸ”₯πŸ”₯πŸ”₯πŸ”₯', + style: Theme.of(context) + .textTheme + .bodyText2 + .copyWith(fontSize: 13, height: 1.5), + ) + ], + ), + ), + Container( + padding: EdgeInsets.only(top: 8.0), + width: double.infinity, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: OutlineButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(4))), + onPressed: () {}, + child: Text( + 'Edit Profile', + style: TextStyle(fontWeight: FontWeight.w500), + ), + ), + ), + SizedBox(width: 12), + Expanded( + child: OutlineButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(4))), + onPressed: () {}, + child: Text( + 'Saved', + style: TextStyle(fontWeight: FontWeight.w500), + ), + ), + ) + ], + ), + ) + ], + ), + ); + } + + Widget _buildItem(String title, String value) { + return Container( + padding: EdgeInsets.all(8), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + value, + style: TextStyle(fontWeight: FontWeight.w800, fontSize: 16), + ), + SizedBox(height: 2), + Text( + title, + style: Theme.of(context).textTheme.bodyText2.copyWith(fontSize: 12), + ) + ], + ), + ); + } +} diff --git a/lib/app/pages/profile/widgets/profile_highlights_widget.dart b/lib/app/pages/profile/widgets/profile_highlights_widget.dart new file mode 100644 index 0000000..fc5cdd5 --- /dev/null +++ b/lib/app/pages/profile/widgets/profile_highlights_widget.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/app/pages/home/widget/home_story_item_widget.dart'; + +class ProfileHighlightsWidget extends StatelessWidget { + @override + Widget build(BuildContext context) { + final itemWidth = (MediaQuery.of(context).size.width - 12.0 * 5) / 5; + + return Container( + color: Colors.white, + height: itemWidth + 40, + child: ListView.separated( + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.horizontal, + itemCount: 10, + itemBuilder: (context, index) { + return Container( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4.0, vertical: 8.0), + child: HomeStoryItemWidget(size: itemWidth))); + }, + separatorBuilder: (context, index) => SizedBox(width: 1.0), + ), + ); + } +} diff --git a/lib/app/pages/profile/widgets/profile_sliver_tabbar_delegate.dart b/lib/app/pages/profile/widgets/profile_sliver_tabbar_delegate.dart new file mode 100644 index 0000000..69c5644 --- /dev/null +++ b/lib/app/pages/profile/widgets/profile_sliver_tabbar_delegate.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; + +class ProfileSliverPersistentHeaderTabBar + extends SliverPersistentHeaderDelegate { + Widget child; + + ProfileSliverPersistentHeaderTabBar({this.child}); + + @override + Widget build( + BuildContext context, double shrinkOffset, bool overlapsContent) { + return child; + } + + @override + double get maxExtent => 50; + + @override + double get minExtent => 50; + + @override + bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) { + return true; + } +} diff --git a/lib/app/pages/splash/splash_screen.dart b/lib/app/pages/splash/splash_screen.dart new file mode 100644 index 0000000..d3ac839 --- /dev/null +++ b/lib/app/pages/splash/splash_screen.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_new_instagram/app/pages/login/sign_in_screen.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; + +class SplashScreen extends StatefulWidget { + @override + _SplashScreenState createState() => _SplashScreenState(); +} + +class _SplashScreenState extends State { + @override + void initState() { + Future.delayed(Duration(seconds: 2)).then((_) => Get.to(SignInScreen())); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + alignment: Alignment.center, + child: SvgPicture.asset(Assets.images.icInstaSplash, fit: BoxFit.fill), + ); + } +} diff --git a/lib/app/widgets/insta_bottom_nav_item.dart b/lib/app/widgets/insta_bottom_nav_item.dart new file mode 100644 index 0000000..4d68bf4 --- /dev/null +++ b/lib/app/widgets/insta_bottom_nav_item.dart @@ -0,0 +1,44 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_new_instagram/gen_assets/assets.gen.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:tuple/tuple.dart'; + +class InstaBottomNavItem extends StatelessWidget { + final Tuple2 icon; + final VoidCallback onPress; + final bool isSelected; + + InstaBottomNavItem(this.icon, this.isSelected, {this.onPress}); + + @override + Widget build(BuildContext context) { + return InkResponse( + onTap: this.onPress, + child: Container( + child: Padding( + padding: EdgeInsets.all(8.0), + child: icon.item1 == null + ? _selfPicture(isSelected) + : SvgPicture.asset( + isSelected ? icon.item2 : icon.item1, + color: Colors.black, + )), + ), + ); + } + + Widget _selfPicture(bool isSelected) { + return CircleAvatar( + radius: 14, + backgroundColor: Colors.black, + child: Padding( + padding: isSelected ? EdgeInsets.all(1.0) : EdgeInsets.all(0), + child: CircleAvatar( + backgroundImage: Assets.images.imagesSample, + radius: 14, + ), + ), + ); + } +} diff --git a/lib/gen_assets/assets.gen.dart b/lib/gen_assets/assets.gen.dart new file mode 100644 index 0000000..5be74b3 --- /dev/null +++ b/lib/gen_assets/assets.gen.dart @@ -0,0 +1,126 @@ +/// GENERATED CODE - DO NOT MODIFY BY HAND +/// ***************************************************** +/// FlutterGen +/// ***************************************************** + +import 'package:flutter/widgets.dart'; + +class $AssetsImagesGen { + const $AssetsImagesGen(); + + String get home24px => 'assets/images/home-24px.svg'; + String get icAaText => 'assets/images/ic_aa_text.svg'; + String get icAccount => 'assets/images/ic_account.svg'; + String get icAccountSelected => 'assets/images/ic_account_selected.svg'; + String get icAddCircle => 'assets/images/ic_add_circle.svg'; + String get icAddNew => 'assets/images/ic_add_new.svg'; + String get icArt => 'assets/images/ic_art.svg'; + String get icBookmark => 'assets/images/ic_bookmark.svg'; + String get icCamera => 'assets/images/ic_camera.svg'; + String get icCameraV2 => 'assets/images/ic_camera_v2.svg'; + String get icComment => 'assets/images/ic_comment.svg'; + String get icCommentOutline => 'assets/images/ic_comment_outline.svg'; + String get icCommentV3 => 'assets/images/ic_comment_v3.svg'; + String get icCreatePost => 'assets/images/ic_create_post.svg'; + String get icExpand => 'assets/images/ic_expand.svg'; + String get icFacebook => 'assets/images/ic_facebook.svg'; + String get icFavorite => 'assets/images/ic_favorite.svg'; + String get icFavoriteSelected => 'assets/images/ic_favorite_selected.svg'; + String get icFeedPost => 'assets/images/ic_feed_post.svg'; + String get icFilterColor => 'assets/images/ic_filter_color.svg'; + String get icFilterCrop => 'assets/images/ic_filter_crop.svg'; + String get icFilterFace => 'assets/images/ic_filter_face.svg'; + String get icFood => 'assets/images/ic_food.svg'; + String get icGallery => 'assets/images/ic_gallery.svg'; + String get icGuide => 'assets/images/ic_guide.svg'; + String get icHeartFilled => 'assets/images/ic_heart_filled.svg'; + String get icHeartOutline => 'assets/images/ic_heart_outline.svg'; + String get icHeartV2 => 'assets/images/ic_heart_v2.svg'; + String get icHome => 'assets/images/ic_home.svg'; + String get icHomeSelected => 'assets/images/ic_home_selected.svg'; + String get icIgtvVideo => 'assets/images/ic_igtv_video.svg'; + String get icInstaSplash => 'assets/images/ic_insta_splash.svg'; + String get icInstagram => 'assets/images/ic_instagram.svg'; + String get icMesenger => 'assets/images/ic_mesenger.svg'; + String get icMulti => 'assets/images/ic_multi.svg'; + String get icMusic => 'assets/images/ic_music.svg'; + String get icPlay => 'assets/images/ic_play.svg'; + String get icProfileAdd => 'assets/images/ic_profile_add.svg'; + String get icProfileNew => 'assets/images/ic_profile_new.svg'; + String get icRotateCamera => 'assets/images/ic_rotate_camera.svg'; + String get icSearch => 'assets/images/ic_search.svg'; + String get icSearchNew => 'assets/images/ic_search_new.svg'; + String get icSearchSelected => 'assets/images/ic_search_selected.svg'; + String get icSend => 'assets/images/ic_send.svg'; + String get icSendDirect => 'assets/images/ic_send_direct.svg'; + String get icSendV3 => 'assets/images/ic_send_v3.svg'; + String get icSetting => 'assets/images/ic_setting.svg'; + String get icShop => 'assets/images/ic_shop.svg'; + String get icStory => 'assets/images/ic_story.svg'; + String get icStoryHighlight => 'assets/images/ic_story_highlight.svg'; + String get icStyle => 'assets/images/ic_style.svg'; + String get icTravel => 'assets/images/ic_travel.svg'; + AssetGenImage get imagesSample => + const AssetGenImage('assets/images/images_sample.jpg'); + AssetGenImage get imagesSample2 => + const AssetGenImage('assets/images/images_sample_2.jpg'); + String get logoInsta => 'assets/images/logo_insta.svg'; +} + +class Assets { + Assets._(); + + static const $AssetsImagesGen images = $AssetsImagesGen(); +} + +class AssetGenImage extends AssetImage { + const AssetGenImage(String assetName) + : _assetName = assetName, + super(assetName); + final String _assetName; + + Image image({ + Key key, + ImageFrameBuilder frameBuilder, + ImageLoadingBuilder loadingBuilder, + ImageErrorWidgetBuilder errorBuilder, + String semanticLabel, + bool excludeFromSemantics = false, + double width, + double height, + Color color, + BlendMode colorBlendMode, + BoxFit fit, + AlignmentGeometry alignment = Alignment.center, + ImageRepeat repeat = ImageRepeat.noRepeat, + Rect centerSlice, + bool matchTextDirection = false, + bool gaplessPlayback = false, + bool isAntiAlias = false, + FilterQuality filterQuality = FilterQuality.low, + }) { + return Image( + key: key, + image: this, + frameBuilder: frameBuilder, + loadingBuilder: loadingBuilder, + errorBuilder: errorBuilder, + semanticLabel: semanticLabel, + excludeFromSemantics: excludeFromSemantics, + width: width, + height: height, + color: color, + colorBlendMode: colorBlendMode, + fit: fit, + alignment: alignment, + repeat: repeat, + centerSlice: centerSlice, + matchTextDirection: matchTextDirection, + gaplessPlayback: gaplessPlayback, + isAntiAlias: isAntiAlias, + filterQuality: filterQuality, + ); + } + + String get path => _assetName; +} diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..ec33b73 --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,791 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + url: "https://pub.dartlang.org" + source: hosted + version: "14.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "0.41.2" + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.13" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.0" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.5.0-nullsafety.1" + bloc: + dependency: transitive + description: + name: bloc + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.1" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0-nullsafety.1" + build: + dependency: transitive + description: + name: build + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.2" + build_config: + dependency: transitive + description: + name: build_config + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.5" + build_daemon: + dependency: transitive + description: + name: build_daemon + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.7" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.3" + build_runner: + dependency: "direct dev" + description: + name: build_runner + url: "https://pub.dartlang.org" + source: hosted + version: "1.11.1" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.7" + built_collection: + dependency: transitive + description: + name: built_collection + url: "https://pub.dartlang.org" + source: hosted + version: "4.3.2" + built_value: + dependency: transitive + description: + name: built_value + url: "https://pub.dartlang.org" + source: hosted + version: "7.1.0" + cached_network_image: + dependency: "direct main" + description: + name: cached_network_image + url: "https://pub.dartlang.org" + source: hosted + version: "2.5.0" + camera: + dependency: "direct main" + description: + name: camera + url: "https://pub.dartlang.org" + source: hosted + version: "0.7.0+2" + camera_platform_interface: + dependency: transitive + description: + name: camera_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0-nullsafety.3" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0-nullsafety.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0-nullsafety.1" + code_builder: + dependency: transitive + description: + name: code_builder + url: "https://pub.dartlang.org" + source: hosted + version: "3.6.0" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.15.0-nullsafety.3" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + cross_file: + dependency: transitive + description: + name: cross_file + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.5" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + dart_style: + dependency: transitive + description: + name: dart_style + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.11" + dartx: + dependency: transitive + description: + name: dartx + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.0" + equatable: + dependency: "direct main" + description: + name: equatable + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.5" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0-nullsafety.1" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "5.2.1" + fixnum: + dependency: transitive + description: + name: fixnum + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.11" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_bloc: + dependency: "direct main" + description: + name: flutter_bloc + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.1" + flutter_blurhash: + dependency: transitive + description: + name: flutter_blurhash + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.0" + flutter_cache_manager: + dependency: transitive + description: + name: flutter_cache_manager + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + flutter_staggered_grid_view: + dependency: "direct main" + description: + name: flutter_staggered_grid_view + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.4" + flutter_svg: + dependency: "direct main" + description: + name: flutter_svg + url: "https://pub.dartlang.org" + source: hosted + version: "0.18.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + get: + dependency: "direct main" + description: + name: get + url: "https://pub.dartlang.org" + source: hosted + version: "3.24.0" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + google_fonts: + dependency: "direct main" + description: + name: google_fonts + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + graphs: + dependency: transitive + description: + name: graphs + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0" + hive: + dependency: "direct main" + description: + name: hive + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.4+1" + hive_flutter: + dependency: "direct main" + description: + name: hive_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.1" + hive_generator: + dependency: "direct dev" + description: + name: hive_generator + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.2" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.2" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.4" + image: + dependency: transitive + description: + name: image + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.19" + intl: + dependency: transitive + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.16.1" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.4" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.2" + json_annotation: + dependency: transitive + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.1" + liquid_pull_to_refresh: + dependency: "direct main" + description: + name: liquid_pull_to_refresh + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "0.11.4" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.10-nullsafety.1" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0-nullsafety.3" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.7" + nested: + dependency: transitive + description: + name: nested + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4" + node_interop: + dependency: transitive + description: + name: node_interop + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" + node_io: + dependency: transitive + description: + name: node_io + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + octo_image: + dependency: transitive + description: + name: octo_image + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.0" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" + path: + dependency: "direct main" + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0-nullsafety.1" + path_drawing: + dependency: transitive + description: + name: path_drawing + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.1+1" + path_parsing: + dependency: transitive + description: + name: path_parsing + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.4" + path_provider: + dependency: "direct main" + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.27" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+2" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4+8" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4+3" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.2" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.1" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.0" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.13" + provider: + dependency: transitive + description: + name: provider + url: "https://pub.dartlang.org" + source: hosted + version: "4.3.3" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.4" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.7" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.5" + rxdart: + dependency: transitive + description: + name: rxdart + url: "https://pub.dartlang.org" + source: hosted + version: "0.25.0" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "0.7.9" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.4" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.10+1" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0-nullsafety.2" + sqflite: + dependency: transitive + description: + name: sqflite + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.2+3" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3+1" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0-nullsafety.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0-nullsafety.1" + stream_transform: + dependency: transitive + description: + name: stream_transform + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0-nullsafety.1" + synchronized: + dependency: transitive + description: + name: synchronized + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0+2" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0-nullsafety.1" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.19-nullsafety.2" + time: + dependency: transitive + description: + name: time + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.0" + timing: + dependency: transitive + description: + name: timing + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.1+3" + tuple: + dependency: "direct main" + description: + name: tuple + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0-nullsafety.3" + uuid: + dependency: transitive + description: + name: uuid + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.2" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0-nullsafety.3" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.7+15" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.4+1" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "4.5.1" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.1" +sdks: + dart: ">=2.10.2 <2.11.0" + flutter: ">=1.22.2 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..01a8e47 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,109 @@ +name: flutter_new_instagram +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.7.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # GetX + get: ^3.24.0 + + google_fonts: ^1.1.2 + flutter_svg: 0.18.0 + + # Hive database with path provider + hive: ^1.4.4 + hive_flutter: ^0.3.1 + path_provider: ^1.6.11 + path: ^1.6.4 + + equatable: ^1.2.5 + flutter_bloc: ^6.1.1 + + liquid_pull_to_refresh: ^2.0.0 + cached_network_image: ^2.0.0-rc.1 + + camera: ^0.7.0+2 + + flutter_staggered_grid_view: ^0.3.4 + # tuple + tuple: ^1.0.3 + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.0 + +dev_dependencies: + flutter_test: + sdk: flutter + + hive_generator: ^0.8.2 + build_runner: ^1.8.0 + +flutter_gen: + output: lib/gen_assets/ + lineLength: 80 + +# 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 + + assets: + - assets/images/ + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/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: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/sample/Screenshot_1614271249.png b/sample/Screenshot_1614271249.png new file mode 100644 index 0000000..4ac8851 Binary files /dev/null and b/sample/Screenshot_1614271249.png differ diff --git a/sample/Screenshot_1614271261.png b/sample/Screenshot_1614271261.png new file mode 100644 index 0000000..e35bfd8 Binary files /dev/null and b/sample/Screenshot_1614271261.png differ diff --git a/sample/Screenshot_1614271272.png b/sample/Screenshot_1614271272.png new file mode 100644 index 0000000..fbe144a Binary files /dev/null and b/sample/Screenshot_1614271272.png differ diff --git a/sample/Screenshot_1614271279.png b/sample/Screenshot_1614271279.png new file mode 100644 index 0000000..a1a7e0d Binary files /dev/null and b/sample/Screenshot_1614271279.png differ diff --git a/sample/Screenshot_1614271300.png b/sample/Screenshot_1614271300.png new file mode 100644 index 0000000..67583f7 Binary files /dev/null and b/sample/Screenshot_1614271300.png differ diff --git a/sample/Screenshot_1614271317.png b/sample/Screenshot_1614271317.png new file mode 100644 index 0000000..5b8837e Binary files /dev/null and b/sample/Screenshot_1614271317.png differ diff --git a/sample/Screenshot_1614271544.png b/sample/Screenshot_1614271544.png new file mode 100644 index 0000000..86803c8 Binary files /dev/null and b/sample/Screenshot_1614271544.png differ diff --git a/sample/Screenshot_1614271565.png b/sample/Screenshot_1614271565.png new file mode 100644 index 0000000..e73b09e Binary files /dev/null and b/sample/Screenshot_1614271565.png differ diff --git a/sample/Screenshot_1614271573.png b/sample/Screenshot_1614271573.png new file mode 100644 index 0000000..93bdca2 Binary files /dev/null and b/sample/Screenshot_1614271573.png differ diff --git a/sample/Screenshot_1614271598.png b/sample/Screenshot_1614271598.png new file mode 100644 index 0000000..d63c2f6 Binary files /dev/null and b/sample/Screenshot_1614271598.png differ diff --git a/sample/Screenshot_1614271609.png b/sample/Screenshot_1614271609.png new file mode 100644 index 0000000..817973b Binary files /dev/null and b/sample/Screenshot_1614271609.png differ diff --git a/test/widget_test.dart b/test/widget_test.dart new file mode 100644 index 0000000..758658e --- /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:flutter_new_instagram/app/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); + }); +}