diff --git a/assets.rar b/assets.rar
deleted file mode 100644
index 297775c..0000000
Binary files a/assets.rar and /dev/null differ
diff --git a/assets/facebook.png b/assets/facebook.png
new file mode 100644
index 0000000..8f49364
Binary files /dev/null and b/assets/facebook.png differ
diff --git a/assets/fonts/Billabong.ttf b/assets/fonts/Billabong.ttf
new file mode 100644
index 0000000..0df4bf6
Binary files /dev/null and b/assets/fonts/Billabong.ttf differ
diff --git a/assets/images/account_active_icon.svg b/assets/images/account_active_icon.svg
new file mode 100644
index 0000000..69ae99a
--- /dev/null
+++ b/assets/images/account_active_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/account_icon.svg b/assets/images/account_icon.svg
new file mode 100644
index 0000000..2b017b9
--- /dev/null
+++ b/assets/images/account_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/camera_icon.svg b/assets/images/camera_icon.svg
new file mode 100644
index 0000000..0279244
--- /dev/null
+++ b/assets/images/camera_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/comment_icon.svg b/assets/images/comment_icon.svg
new file mode 100644
index 0000000..c50fdf9
--- /dev/null
+++ b/assets/images/comment_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/home_active_icon.svg b/assets/images/home_active_icon.svg
new file mode 100644
index 0000000..a1e5803
--- /dev/null
+++ b/assets/images/home_active_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/home_icon.svg b/assets/images/home_icon.svg
new file mode 100644
index 0000000..f6b1ffa
--- /dev/null
+++ b/assets/images/home_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/love_active_icon.svg b/assets/images/love_active_icon.svg
new file mode 100644
index 0000000..04fefb6
--- /dev/null
+++ b/assets/images/love_active_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/love_icon.svg b/assets/images/love_icon.svg
new file mode 100644
index 0000000..3b65caf
--- /dev/null
+++ b/assets/images/love_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/loved_icon.svg b/assets/images/loved_icon.svg
new file mode 100644
index 0000000..c70376e
--- /dev/null
+++ b/assets/images/loved_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/message_icon.svg b/assets/images/message_icon.svg
new file mode 100644
index 0000000..2f96bc5
--- /dev/null
+++ b/assets/images/message_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/save_icon.svg b/assets/images/save_icon.svg
new file mode 100644
index 0000000..a141198
--- /dev/null
+++ b/assets/images/save_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/search_active_icon.svg b/assets/images/search_active_icon.svg
new file mode 100644
index 0000000..1d5b6b3
--- /dev/null
+++ b/assets/images/search_active_icon.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/assets/images/search_icon.svg b/assets/images/search_icon.svg
new file mode 100644
index 0000000..6a1fd2f
--- /dev/null
+++ b/assets/images/search_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/upload_active_icon.svg b/assets/images/upload_active_icon.svg
new file mode 100644
index 0000000..954ba39
--- /dev/null
+++ b/assets/images/upload_active_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/upload_icon.svg b/assets/images/upload_icon.svg
new file mode 100644
index 0000000..ec71556
--- /dev/null
+++ b/assets/images/upload_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/instagram_logo.png b/assets/instagram_logo.png
new file mode 100644
index 0000000..6b66c82
Binary files /dev/null and b/assets/instagram_logo.png differ
diff --git a/clone-instagram-login-Refactoring.zip b/clone-instagram-login-Refactoring.zip
deleted file mode 100644
index 8bfb817..0000000
Binary files a/clone-instagram-login-Refactoring.zip and /dev/null differ
diff --git a/clone-instagram-login-Refactoring/.gitignore b/clone-instagram-login-Refactoring/.gitignore
new file mode 100644
index 0000000..4c574d1
--- /dev/null
+++ b/clone-instagram-login-Refactoring/.gitignore
@@ -0,0 +1,46 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+migrate_working_dir/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+**/ios/Flutter/.last_build_id
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+/build/
+
+# Symbolication related
+app.*.symbols
+
+# Obfuscation related
+app.*.map.json
+
+# Android Studio will place build artifacts here
+/android/app/debug
+/android/app/profile
+/android/app/release
+
+coverage/
diff --git a/clone-instagram-login-Refactoring/.metadata b/clone-instagram-login-Refactoring/.metadata
new file mode 100644
index 0000000..262ceed
--- /dev/null
+++ b/clone-instagram-login-Refactoring/.metadata
@@ -0,0 +1,45 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled.
+
+version:
+ revision: 135454af32477f815a7525073027a3ff9eff1bfd
+ channel: stable
+
+project_type: app
+
+# Tracks metadata for the flutter migrate command
+migration:
+ platforms:
+ - platform: root
+ create_revision: 135454af32477f815a7525073027a3ff9eff1bfd
+ base_revision: 135454af32477f815a7525073027a3ff9eff1bfd
+ - platform: android
+ create_revision: 135454af32477f815a7525073027a3ff9eff1bfd
+ base_revision: 135454af32477f815a7525073027a3ff9eff1bfd
+ - platform: ios
+ create_revision: 135454af32477f815a7525073027a3ff9eff1bfd
+ base_revision: 135454af32477f815a7525073027a3ff9eff1bfd
+ - platform: linux
+ create_revision: 135454af32477f815a7525073027a3ff9eff1bfd
+ base_revision: 135454af32477f815a7525073027a3ff9eff1bfd
+ - platform: macos
+ create_revision: 135454af32477f815a7525073027a3ff9eff1bfd
+ base_revision: 135454af32477f815a7525073027a3ff9eff1bfd
+ - platform: web
+ create_revision: 135454af32477f815a7525073027a3ff9eff1bfd
+ base_revision: 135454af32477f815a7525073027a3ff9eff1bfd
+ - platform: windows
+ create_revision: 135454af32477f815a7525073027a3ff9eff1bfd
+ base_revision: 135454af32477f815a7525073027a3ff9eff1bfd
+
+ # User provided section
+
+ # List of Local paths (relative to this file) that should be
+ # ignored by the migrate tool.
+ #
+ # Files that are not part of the templates will be ignored by default.
+ unmanaged_files:
+ - 'lib/main.dart'
+ - 'ios/Runner.xcodeproj/project.pbxproj'
diff --git a/clone-instagram-login-Refactoring/README.md b/clone-instagram-login-Refactoring/README.md
new file mode 100644
index 0000000..3a713d8
--- /dev/null
+++ b/clone-instagram-login-Refactoring/README.md
@@ -0,0 +1,16 @@
+# example_widget_testing
+
+A new Flutter project.
+
+## Getting Started
+
+This project is a starting point for a Flutter application.
+
+A few resources to get you started if this is your first Flutter project:
+
+- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
+- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
+
+For help getting started with Flutter development, view the
+[online documentation](https://docs.flutter.dev/), which offers tutorials,
+samples, guidance on mobile development, and a full API reference.
diff --git a/clone-instagram-login-Refactoring/analysis_options.yaml b/clone-instagram-login-Refactoring/analysis_options.yaml
new file mode 100644
index 0000000..61b6c4d
--- /dev/null
+++ b/clone-instagram-login-Refactoring/analysis_options.yaml
@@ -0,0 +1,29 @@
+# This file configures the analyzer, which statically analyzes Dart code to
+# check for errors, warnings, and lints.
+#
+# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
+# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
+# invoked from the command line by running `flutter analyze`.
+
+# The following line activates a set of recommended lints for Flutter apps,
+# packages, and plugins designed to encourage good coding practices.
+include: package:flutter_lints/flutter.yaml
+
+linter:
+ # The lint rules applied to this project can be customized in the
+ # section below to disable rules from the `package:flutter_lints/flutter.yaml`
+ # included above or to enable additional rules. A list of all available lints
+ # and their documentation is published at
+ # https://dart-lang.github.io/linter/lints/index.html.
+ #
+ # Instead of disabling a lint rule for the entire project in the
+ # section below, it can also be suppressed for a single line of code
+ # or a specific dart file by using the `// ignore: name_of_lint` and
+ # `// ignore_for_file: name_of_lint` syntax on the line or in the file
+ # producing the lint.
+ rules:
+ # avoid_print: false # Uncomment to disable the `avoid_print` rule
+ # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options
diff --git a/clone-instagram-login-Refactoring/android/.gitignore b/clone-instagram-login-Refactoring/android/.gitignore
new file mode 100644
index 0000000..6f56801
--- /dev/null
+++ b/clone-instagram-login-Refactoring/android/.gitignore
@@ -0,0 +1,13 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
+
+# Remember to never publicly share your keystore.
+# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
+key.properties
+**/*.keystore
+**/*.jks
diff --git a/clone-instagram-login-Refactoring/android/app/build.gradle b/clone-instagram-login-Refactoring/android/app/build.gradle
new file mode 100644
index 0000000..afb45ef
--- /dev/null
+++ b/clone-instagram-login-Refactoring/android/app/build.gradle
@@ -0,0 +1,71 @@
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+ localPropertiesFile.withReader('UTF-8') { reader ->
+ localProperties.load(reader)
+ }
+}
+
+def flutterRoot = localProperties.getProperty('flutter.sdk')
+if (flutterRoot == null) {
+ throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+}
+
+def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
+if (flutterVersionCode == null) {
+ flutterVersionCode = '1'
+}
+
+def flutterVersionName = localProperties.getProperty('flutter.versionName')
+if (flutterVersionName == null) {
+ flutterVersionName = '1.0'
+}
+
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+ compileSdkVersion flutter.compileSdkVersion
+ ndkVersion flutter.ndkVersion
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+
+ sourceSets {
+ main.java.srcDirs += 'src/main/kotlin'
+ }
+
+ defaultConfig {
+ // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
+ applicationId "com.example.example_widget_testing"
+ // You can update the following values to match your application needs.
+ // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
+ minSdkVersion flutter.minSdkVersion
+ targetSdkVersion flutter.targetSdkVersion
+ versionCode flutterVersionCode.toInteger()
+ versionName flutterVersionName
+ }
+
+ buildTypes {
+ release {
+ // TODO: Add your own signing config for the release build.
+ // Signing with the debug keys for now, so `flutter run --release` works.
+ signingConfig signingConfigs.debug
+ }
+ }
+}
+
+flutter {
+ source '../..'
+}
+
+dependencies {
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
diff --git a/clone-instagram-login-Refactoring/android/app/src/debug/AndroidManifest.xml b/clone-instagram-login-Refactoring/android/app/src/debug/AndroidManifest.xml
new file mode 100644
index 0000000..d606aaa
--- /dev/null
+++ b/clone-instagram-login-Refactoring/android/app/src/debug/AndroidManifest.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/clone-instagram-login-Refactoring/android/app/src/main/AndroidManifest.xml b/clone-instagram-login-Refactoring/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..27601fa
--- /dev/null
+++ b/clone-instagram-login-Refactoring/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/clone-instagram-login-Refactoring/android/app/src/main/kotlin/com/example/example_widget_testing/MainActivity.kt b/clone-instagram-login-Refactoring/android/app/src/main/kotlin/com/example/example_widget_testing/MainActivity.kt
new file mode 100644
index 0000000..4d5c3cc
--- /dev/null
+++ b/clone-instagram-login-Refactoring/android/app/src/main/kotlin/com/example/example_widget_testing/MainActivity.kt
@@ -0,0 +1,6 @@
+package com.example.example_widget_testing
+
+import io.flutter.embedding.android.FlutterActivity
+
+class MainActivity: FlutterActivity() {
+}
diff --git a/clone-instagram-login-Refactoring/android/app/src/main/res/drawable-v21/launch_background.xml b/clone-instagram-login-Refactoring/android/app/src/main/res/drawable-v21/launch_background.xml
new file mode 100644
index 0000000..f74085f
--- /dev/null
+++ b/clone-instagram-login-Refactoring/android/app/src/main/res/drawable-v21/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/clone-instagram-login-Refactoring/android/app/src/main/res/drawable/launch_background.xml b/clone-instagram-login-Refactoring/android/app/src/main/res/drawable/launch_background.xml
new file mode 100644
index 0000000..304732f
--- /dev/null
+++ b/clone-instagram-login-Refactoring/android/app/src/main/res/drawable/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/clone-instagram-login-Refactoring/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/clone-instagram-login-Refactoring/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..db77bb4
Binary files /dev/null and b/clone-instagram-login-Refactoring/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/clone-instagram-login-Refactoring/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/clone-instagram-login-Refactoring/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..17987b7
Binary files /dev/null and b/clone-instagram-login-Refactoring/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/clone-instagram-login-Refactoring/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/clone-instagram-login-Refactoring/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..09d4391
Binary files /dev/null and b/clone-instagram-login-Refactoring/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/clone-instagram-login-Refactoring/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/clone-instagram-login-Refactoring/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..d5f1c8d
Binary files /dev/null and b/clone-instagram-login-Refactoring/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/clone-instagram-login-Refactoring/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/clone-instagram-login-Refactoring/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4d6372e
Binary files /dev/null and b/clone-instagram-login-Refactoring/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/clone-instagram-login-Refactoring/android/app/src/main/res/values-night/styles.xml b/clone-instagram-login-Refactoring/android/app/src/main/res/values-night/styles.xml
new file mode 100644
index 0000000..06952be
--- /dev/null
+++ b/clone-instagram-login-Refactoring/android/app/src/main/res/values-night/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/clone-instagram-login-Refactoring/android/app/src/main/res/values/styles.xml b/clone-instagram-login-Refactoring/android/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..cb1ef88
--- /dev/null
+++ b/clone-instagram-login-Refactoring/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/clone-instagram-login-Refactoring/android/app/src/profile/AndroidManifest.xml b/clone-instagram-login-Refactoring/android/app/src/profile/AndroidManifest.xml
new file mode 100644
index 0000000..d606aaa
--- /dev/null
+++ b/clone-instagram-login-Refactoring/android/app/src/profile/AndroidManifest.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/clone-instagram-login-Refactoring/android/build.gradle b/clone-instagram-login-Refactoring/android/build.gradle
new file mode 100644
index 0000000..83ae220
--- /dev/null
+++ b/clone-instagram-login-Refactoring/android/build.gradle
@@ -0,0 +1,31 @@
+buildscript {
+ ext.kotlin_version = '1.6.10'
+ repositories {
+ google()
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:7.1.2'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+ project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+ project.evaluationDependsOn(':app')
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/clone-instagram-login-Refactoring/android/gradle.properties b/clone-instagram-login-Refactoring/android/gradle.properties
new file mode 100644
index 0000000..94adc3a
--- /dev/null
+++ b/clone-instagram-login-Refactoring/android/gradle.properties
@@ -0,0 +1,3 @@
+org.gradle.jvmargs=-Xmx1536M
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/clone-instagram-login-Refactoring/android/gradle/wrapper/gradle-wrapper.properties b/clone-instagram-login-Refactoring/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..cb24abd
--- /dev/null
+++ b/clone-instagram-login-Refactoring/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
diff --git a/clone-instagram-login-Refactoring/android/settings.gradle b/clone-instagram-login-Refactoring/android/settings.gradle
new file mode 100644
index 0000000..44e62bc
--- /dev/null
+++ b/clone-instagram-login-Refactoring/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/clone-instagram-login-Refactoring/assets/facebook.png b/clone-instagram-login-Refactoring/assets/facebook.png
new file mode 100644
index 0000000..8f49364
Binary files /dev/null and b/clone-instagram-login-Refactoring/assets/facebook.png differ
diff --git a/clone-instagram-login-Refactoring/assets/fonts/Billabong.ttf b/clone-instagram-login-Refactoring/assets/fonts/Billabong.ttf
new file mode 100644
index 0000000..0df4bf6
Binary files /dev/null and b/clone-instagram-login-Refactoring/assets/fonts/Billabong.ttf differ
diff --git a/clone-instagram-login-Refactoring/assets/images/account_active_icon.svg b/clone-instagram-login-Refactoring/assets/images/account_active_icon.svg
new file mode 100644
index 0000000..69ae99a
--- /dev/null
+++ b/clone-instagram-login-Refactoring/assets/images/account_active_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/clone-instagram-login-Refactoring/assets/images/account_icon.svg b/clone-instagram-login-Refactoring/assets/images/account_icon.svg
new file mode 100644
index 0000000..2b017b9
--- /dev/null
+++ b/clone-instagram-login-Refactoring/assets/images/account_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/clone-instagram-login-Refactoring/assets/images/camera_icon.svg b/clone-instagram-login-Refactoring/assets/images/camera_icon.svg
new file mode 100644
index 0000000..0279244
--- /dev/null
+++ b/clone-instagram-login-Refactoring/assets/images/camera_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/clone-instagram-login-Refactoring/assets/images/comment_icon.svg b/clone-instagram-login-Refactoring/assets/images/comment_icon.svg
new file mode 100644
index 0000000..c50fdf9
--- /dev/null
+++ b/clone-instagram-login-Refactoring/assets/images/comment_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/clone-instagram-login-Refactoring/assets/images/home_active_icon.svg b/clone-instagram-login-Refactoring/assets/images/home_active_icon.svg
new file mode 100644
index 0000000..a1e5803
--- /dev/null
+++ b/clone-instagram-login-Refactoring/assets/images/home_active_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/clone-instagram-login-Refactoring/assets/images/home_icon.svg b/clone-instagram-login-Refactoring/assets/images/home_icon.svg
new file mode 100644
index 0000000..f6b1ffa
--- /dev/null
+++ b/clone-instagram-login-Refactoring/assets/images/home_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/clone-instagram-login-Refactoring/assets/images/love_active_icon.svg b/clone-instagram-login-Refactoring/assets/images/love_active_icon.svg
new file mode 100644
index 0000000..04fefb6
--- /dev/null
+++ b/clone-instagram-login-Refactoring/assets/images/love_active_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/clone-instagram-login-Refactoring/assets/images/love_icon.svg b/clone-instagram-login-Refactoring/assets/images/love_icon.svg
new file mode 100644
index 0000000..3b65caf
--- /dev/null
+++ b/clone-instagram-login-Refactoring/assets/images/love_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/clone-instagram-login-Refactoring/assets/images/loved_icon.svg b/clone-instagram-login-Refactoring/assets/images/loved_icon.svg
new file mode 100644
index 0000000..c70376e
--- /dev/null
+++ b/clone-instagram-login-Refactoring/assets/images/loved_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/clone-instagram-login-Refactoring/assets/images/message_icon.svg b/clone-instagram-login-Refactoring/assets/images/message_icon.svg
new file mode 100644
index 0000000..2f96bc5
--- /dev/null
+++ b/clone-instagram-login-Refactoring/assets/images/message_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/clone-instagram-login-Refactoring/assets/images/save_icon.svg b/clone-instagram-login-Refactoring/assets/images/save_icon.svg
new file mode 100644
index 0000000..a141198
--- /dev/null
+++ b/clone-instagram-login-Refactoring/assets/images/save_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/clone-instagram-login-Refactoring/assets/images/search_active_icon.svg b/clone-instagram-login-Refactoring/assets/images/search_active_icon.svg
new file mode 100644
index 0000000..1d5b6b3
--- /dev/null
+++ b/clone-instagram-login-Refactoring/assets/images/search_active_icon.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/clone-instagram-login-Refactoring/assets/images/search_icon.svg b/clone-instagram-login-Refactoring/assets/images/search_icon.svg
new file mode 100644
index 0000000..6a1fd2f
--- /dev/null
+++ b/clone-instagram-login-Refactoring/assets/images/search_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/clone-instagram-login-Refactoring/assets/images/upload_active_icon.svg b/clone-instagram-login-Refactoring/assets/images/upload_active_icon.svg
new file mode 100644
index 0000000..954ba39
--- /dev/null
+++ b/clone-instagram-login-Refactoring/assets/images/upload_active_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/clone-instagram-login-Refactoring/assets/images/upload_icon.svg b/clone-instagram-login-Refactoring/assets/images/upload_icon.svg
new file mode 100644
index 0000000..ec71556
--- /dev/null
+++ b/clone-instagram-login-Refactoring/assets/images/upload_icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/clone-instagram-login-Refactoring/assets/instagram_logo.png b/clone-instagram-login-Refactoring/assets/instagram_logo.png
new file mode 100644
index 0000000..6b66c82
Binary files /dev/null and b/clone-instagram-login-Refactoring/assets/instagram_logo.png differ
diff --git a/clone-instagram-login-Refactoring/integration_test/app_test.dart b/clone-instagram-login-Refactoring/integration_test/app_test.dart
new file mode 100644
index 0000000..1ada004
--- /dev/null
+++ b/clone-instagram-login-Refactoring/integration_test/app_test.dart
@@ -0,0 +1,206 @@
+import 'package:example_widget_testing/app/modules/account/account_page.dart';
+import 'package:example_widget_testing/app/modules/activity/activity_page.dart';
+import 'package:example_widget_testing/app/modules/home/home_page.dart';
+import 'package:example_widget_testing/app/modules/login/login_page.dart';
+import 'package:example_widget_testing/app/modules/post/post_page.dart';
+import 'package:example_widget_testing/app/modules/search/search_page.dart';
+import 'package:example_widget_testing/app/modules/upload/upload_page.dart';
+import 'package:example_widget_testing/core/values/constant/post_json.dart';
+import 'package:example_widget_testing/core/values/constant/profile_json.dart';
+import 'package:example_widget_testing/core/values/constant/search_json.dart';
+import 'package:example_widget_testing/core/values/constant/story_json.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:integration_test/integration_test.dart';
+
+void main() {
+ IntegrationTestWidgetsFlutterBinding.ensureInitialized();
+
+ var routes = {
+ '/login': (context) => const LoginPage(),
+ '/home': (context) =>
+ HomePage(posts: posts, stories: stories, profileData: profileJson),
+ '/search': (context) => SearchPage(searchPosts: searchImages),
+ '/upload': (context) => const UploadPage(),
+ '/activity': (context) => const ActivityPage(),
+ '/account': (context) =>
+ AccountPage(profileData: profileJson, posts: posts, stories: stories),
+ '/post': (context) => PostPage(posts: posts),
+ };
+
+ group('end-to-end test', () {
+ testWidgets('Change dropdown value', (tester) async {
+ await tester.pumpWidget(MaterialApp(
+ home: const LoginPage(),
+ routes: routes,
+ ));
+
+ // find DropdownButton with key language_dropdown
+ final Finder dropdownButton = find.byKey(const Key('language_dropdown'));
+
+ // expect DropdownButton is found
+ expect(dropdownButton, findsOneWidget);
+
+ expect(find.text('English'), findsOneWidget);
+
+ // tap on DropdownButton
+ await tester.tap(dropdownButton);
+
+ // move to next frame
+ await tester.pumpAndSettle();
+
+ // find DropdownMenuItem with key language_dropdown_item_Arabic
+ final Finder dropdownMenuItem =
+ find.byKey(const Key("language_dropdown_item_Italian"));
+
+ expect(dropdownMenuItem, findsNWidgets(2));
+
+ // tap on DropdownMenuItem
+ await tester.tap(dropdownMenuItem.last);
+
+ // move to next frame
+ await tester.pumpAndSettle();
+
+ // expect find text Arabic
+ expect(find.text('Italian'), findsOneWidget);
+ });
+
+ testWidgets('Fill username and password then tap on login button',
+ (tester) async {
+ await tester.pumpWidget(MaterialApp(
+ home: const LoginPage(),
+ routes: routes,
+ ));
+
+ // find TextField with key password_textfield
+ final Finder passwordTextField =
+ find.byKey(const Key('password_textfield'));
+
+ // enter text into TextField
+ await tester.enterText(passwordTextField, 'test');
+
+ // find ElevatedButton with key login_button_elevated_button
+ final Finder loginButton =
+ find.byKey(const Key('login_button_elevated_button'));
+
+ // tap on ElevatedButton
+ await tester.tap(loginButton);
+
+ // expect nothing happen
+ await tester.pumpAndSettle();
+
+ // find AppBar with key home_page_appbar
+ final Finder appBar = find.byKey(const Key('home_page_appbar'));
+
+ // check if AppBar is not found
+ expect(appBar, findsNothing);
+ });
+
+ testWidgets('Fill username and password then tap on login button',
+ (tester) async {
+ // Load app widget.
+ await tester.pumpWidget(MaterialApp(
+ home: const LoginPage(),
+ routes: routes,
+ ));
+
+ // find TextField with key username_textfield
+ final Finder usernameTextField =
+ find.byKey(const Key('username_textfield'));
+
+ // enter text into TextField
+ await tester.enterText(usernameTextField, 'test');
+
+ // find TextField with key password_textfield
+ final Finder passwordTextField =
+ find.byKey(const Key('password_textfield'));
+
+ // enter text into TextField
+ await tester.enterText(passwordTextField, 'test');
+
+ // find ElevatedButton with key login_button_elevated_button
+ final Finder loginButton =
+ find.byKey(const Key('login_button_elevated_button'));
+
+ // tap on ElevatedButton
+ await tester.tap(loginButton);
+
+ // move to next frame
+ await tester.pumpAndSettle();
+
+ // find AppBar with key home_page_appbar
+ final Finder appBar = find.byKey(const Key('home_page_appbar'));
+
+ // check if AppBar is found
+ expect(appBar, findsOneWidget);
+ });
+
+ testWidgets('Open home page then navigate to search page', (tester) async {
+ // Load app widget.
+ await tester.pumpWidget(MaterialApp(
+ home: HomePage(
+ posts: posts,
+ stories: stories,
+ profileData: profileJson,
+ ),
+ routes: routes,
+ ));
+
+ // scroll to bottom
+ await tester.fling(
+ find.byKey(const Key('home_page_single_child_scroll_view')),
+ const Offset(0, 300),
+ 1000,
+ );
+
+ // find search icon in bottom navbar
+ final Finder searchIcon = find.byKey(const Key('bottom_item_1'));
+
+ // tap on search icon
+ await tester.tap(searchIcon);
+
+ // move to next frame
+ await tester.pumpAndSettle(const Duration(seconds: 5));
+
+ // navigate to search page
+ expect(find.byKey(const Key('search_page_app_bar_preferred_size')),
+ findsOneWidget);
+
+ // find search up icon in search page
+ final Finder uploadIcon = find.byKey(const Key('bottom_item_2'));
+
+ // tap on upload icon
+ await tester.tap(uploadIcon);
+
+ // move to next frame
+ await tester.pumpAndSettle();
+
+ // navigate to upload page
+ expect(find.byKey(const Key('upload_page_appbar')), findsOneWidget);
+
+ // find activity icon in bottom navbar
+ final Finder activityIcon = find.byKey(const Key('bottom_item_3'));
+
+ // tap on activity icon
+ await tester.tap(activityIcon);
+
+ // move to next frame
+ await tester.pumpAndSettle();
+
+ // navigate to activity page
+ expect(find.byKey(const Key('activity_page_appbar')), findsOneWidget);
+
+ // find account icon in bottom navbar
+ final Finder accountIcon = find.byKey(const Key('bottom_item_4'));
+
+ // tap on account icon
+ await tester.tap(accountIcon);
+
+ // move to next frame
+ await tester.pumpAndSettle();
+
+ // navigate to account page
+ expect(find.byKey(const Key('app_bar_account')), findsOneWidget);
+ });
+ });
+}
diff --git a/clone-instagram-login-Refactoring/integration_test/calculator_test.dart b/clone-instagram-login-Refactoring/integration_test/calculator_test.dart
new file mode 100644
index 0000000..ba8b78b
--- /dev/null
+++ b/clone-instagram-login-Refactoring/integration_test/calculator_test.dart
@@ -0,0 +1,61 @@
+import 'package:example_widget_testing/app/modules/calculator.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:integration_test/integration_test.dart';
+
+void main() {
+ IntegrationTestWidgetsFlutterBinding.ensureInitialized();
+
+ group('end-to-end test', () {
+ testWidgets('Change dropdown value', (tester) async {
+ await tester.pumpWidget(
+ const MaterialApp(
+ home: SimpleCalculator(),
+ ),
+ );
+
+ const variableA = '2';
+ const variableB = '3';
+ const result = '5';
+
+ // find text field with key variableA
+ final Finder variableAField = find.byKey(const Key('variableA'));
+
+ // expect text field is found
+ expect(variableAField, findsOneWidget);
+
+ // find text field with key variableB
+ final Finder variableBField = find.byKey(const Key('variableB'));
+
+ // expect text field is found
+ expect(variableBField, findsOneWidget);
+
+ // enter text 2
+ await tester.enterText(variableAField, variableA);
+
+ // enter text 3
+ await tester.enterText(variableBField, variableB);
+
+ // find button with key addButton
+ final Finder addButton = find.byKey(const Key('addButton'));
+
+ // expect button is found
+ expect(addButton, findsOneWidget);
+
+ // tap on button
+ await tester.tap(addButton);
+
+ // move to next frame
+ await tester.pumpAndSettle();
+
+ // find text with key result
+ final Finder resultTextFinder = find.byKey(const Key('result'));
+
+ // expect text is found
+ expect(resultTextFinder, findsOneWidget);
+
+ // expect text is 5
+ expect(find.text(result), findsOneWidget);
+ });
+ });
+}
diff --git a/clone-instagram-login-Refactoring/ios/.gitignore b/clone-instagram-login-Refactoring/ios/.gitignore
new file mode 100644
index 0000000..7a7f987
--- /dev/null
+++ b/clone-instagram-login-Refactoring/ios/.gitignore
@@ -0,0 +1,34 @@
+**/dgph
+*.mode1v3
+*.mode2v3
+*.moved-aside
+*.pbxuser
+*.perspectivev3
+**/*sync/
+.sconsign.dblite
+.tags*
+**/.vagrant/
+**/DerivedData/
+Icon?
+**/Pods/
+**/.symlinks/
+profile
+xcuserdata
+**/.generated/
+Flutter/App.framework
+Flutter/Flutter.framework
+Flutter/Flutter.podspec
+Flutter/Generated.xcconfig
+Flutter/ephemeral/
+Flutter/app.flx
+Flutter/app.zip
+Flutter/flutter_assets/
+Flutter/flutter_export_environment.sh
+ServiceDefinitions.json
+Runner/GeneratedPluginRegistrant.*
+
+# Exceptions to above rules.
+!default.mode1v3
+!default.mode2v3
+!default.pbxuser
+!default.perspectivev3
diff --git a/clone-instagram-login-Refactoring/ios/Flutter/AppFrameworkInfo.plist b/clone-instagram-login-Refactoring/ios/Flutter/AppFrameworkInfo.plist
new file mode 100644
index 0000000..9625e10
--- /dev/null
+++ b/clone-instagram-login-Refactoring/ios/Flutter/AppFrameworkInfo.plist
@@ -0,0 +1,26 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ App
+ CFBundleIdentifier
+ io.flutter.flutter.app
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ App
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+ MinimumOSVersion
+ 11.0
+
+
diff --git a/clone-instagram-login-Refactoring/ios/Flutter/Debug.xcconfig b/clone-instagram-login-Refactoring/ios/Flutter/Debug.xcconfig
new file mode 100644
index 0000000..592ceee
--- /dev/null
+++ b/clone-instagram-login-Refactoring/ios/Flutter/Debug.xcconfig
@@ -0,0 +1 @@
+#include "Generated.xcconfig"
diff --git a/clone-instagram-login-Refactoring/ios/Flutter/Release.xcconfig b/clone-instagram-login-Refactoring/ios/Flutter/Release.xcconfig
new file mode 100644
index 0000000..592ceee
--- /dev/null
+++ b/clone-instagram-login-Refactoring/ios/Flutter/Release.xcconfig
@@ -0,0 +1 @@
+#include "Generated.xcconfig"
diff --git a/clone-instagram-login-Refactoring/ios/Runner.xcodeproj/project.pbxproj b/clone-instagram-login-Refactoring/ios/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..1d56de4
--- /dev/null
+++ b/clone-instagram-login-Refactoring/ios/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,481 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 50;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
+ 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
+ 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 97C146EB1CF9000F007C117D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 9740EEB11CF90186004384FC /* Flutter */ = {
+ isa = PBXGroup;
+ children = (
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */,
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */,
+ );
+ name = Flutter;
+ sourceTree = "";
+ };
+ 97C146E51CF9000F007C117D = {
+ isa = PBXGroup;
+ children = (
+ 9740EEB11CF90186004384FC /* Flutter */,
+ 97C146F01CF9000F007C117D /* Runner */,
+ 97C146EF1CF9000F007C117D /* Products */,
+ );
+ sourceTree = "";
+ };
+ 97C146EF1CF9000F007C117D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146EE1CF9000F007C117D /* Runner.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 97C146F01CF9000F007C117D /* Runner */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146FA1CF9000F007C117D /* Main.storyboard */,
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */,
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
+ 97C147021CF9000F007C117D /* Info.plist */,
+ 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 = 1300;
+ ORGANIZATIONNAME = "";
+ TargetAttributes = {
+ 97C146ED1CF9000F007C117D = {
+ CreatedOnToolsVersion = 7.3.1;
+ LastSwiftMigration = 1100;
+ };
+ };
+ };
+ buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 97C146E51CF9000F007C117D;
+ productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 97C146ED1CF9000F007C117D /* Runner */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 97C146EC1CF9000F007C117D /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Thin Binary";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
+ };
+ 9740EEB61CF901F6004384FC /* Run Script */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Run Script";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 97C146EA1CF9000F007C117D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C146FB1CF9000F007C117D /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C147001CF9000F007C117D /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 249021D3217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Profile;
+ };
+ 249021D4217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.exampleWidgetTesting;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Profile;
+ };
+ 97C147031CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 97C147041CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 97C147061CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.exampleWidgetTesting;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Debug;
+ };
+ 97C147071CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.exampleWidgetTesting;
+ 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/clone-instagram-login-Refactoring/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/clone-instagram-login-Refactoring/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/clone-instagram-login-Refactoring/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/clone-instagram-login-Refactoring/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/clone-instagram-login-Refactoring/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/clone-instagram-login-Refactoring/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/clone-instagram-login-Refactoring/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/clone-instagram-login-Refactoring/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000..f9b0d7c
--- /dev/null
+++ b/clone-instagram-login-Refactoring/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+
+
+
+
+ PreviewsEnabled
+
+
+
diff --git a/clone-instagram-login-Refactoring/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/clone-instagram-login-Refactoring/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
new file mode 100644
index 0000000..c87d15a
--- /dev/null
+++ b/clone-instagram-login-Refactoring/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/clone-instagram-login-Refactoring/ios/Runner.xcworkspace/contents.xcworkspacedata b/clone-instagram-login-Refactoring/ios/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..1d526a1
--- /dev/null
+++ b/clone-instagram-login-Refactoring/ios/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/clone-instagram-login-Refactoring/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/clone-instagram-login-Refactoring/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/clone-instagram-login-Refactoring/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/clone-instagram-login-Refactoring/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/clone-instagram-login-Refactoring/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000..f9b0d7c
--- /dev/null
+++ b/clone-instagram-login-Refactoring/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+
+
+
+
+ PreviewsEnabled
+
+
+
diff --git a/clone-instagram-login-Refactoring/ios/Runner/AppDelegate.swift b/clone-instagram-login-Refactoring/ios/Runner/AppDelegate.swift
new file mode 100644
index 0000000..70693e4
--- /dev/null
+++ b/clone-instagram-login-Refactoring/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/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..d36b1fa
--- /dev/null
+++ b/clone-instagram-login-Refactoring/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/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
new file mode 100644
index 0000000..dc9ada4
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
new file mode 100644
index 0000000..28c6bf0
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
new file mode 100644
index 0000000..2ccbfd9
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
new file mode 100644
index 0000000..f091b6b
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
new file mode 100644
index 0000000..4cde121
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
new file mode 100644
index 0000000..d0ef06e
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
new file mode 100644
index 0000000..dcdc230
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
new file mode 100644
index 0000000..2ccbfd9
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
new file mode 100644
index 0000000..c8f9ed8
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
new file mode 100644
index 0000000..a6d6b86
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
new file mode 100644
index 0000000..a6d6b86
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
new file mode 100644
index 0000000..75b2d16
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
new file mode 100644
index 0000000..c4df70d
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
new file mode 100644
index 0000000..6a84f41
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/clone-instagram-login-Refactoring/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/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
new file mode 100644
index 0000000..0bedcf2
--- /dev/null
+++ b/clone-instagram-login-Refactoring/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/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
new file mode 100644
index 0000000..9da19ea
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
new file mode 100644
index 0000000..9da19ea
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
new file mode 100644
index 0000000..9da19ea
Binary files /dev/null and b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/clone-instagram-login-Refactoring/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
new file mode 100644
index 0000000..89c2725
--- /dev/null
+++ b/clone-instagram-login-Refactoring/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/clone-instagram-login-Refactoring/ios/Runner/Base.lproj/LaunchScreen.storyboard b/clone-instagram-login-Refactoring/ios/Runner/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 0000000..f2e259c
--- /dev/null
+++ b/clone-instagram-login-Refactoring/ios/Runner/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Base.lproj/Main.storyboard b/clone-instagram-login-Refactoring/ios/Runner/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..f3c2851
--- /dev/null
+++ b/clone-instagram-login-Refactoring/ios/Runner/Base.lproj/Main.storyboard
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Info.plist b/clone-instagram-login-Refactoring/ios/Runner/Info.plist
new file mode 100644
index 0000000..5dfe479
--- /dev/null
+++ b/clone-instagram-login-Refactoring/ios/Runner/Info.plist
@@ -0,0 +1,51 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleDisplayName
+ Example Widget Testing
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ example_widget_testing
+ 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
+
+ CADisableMinimumFrameDurationOnPhone
+
+ UIApplicationSupportsIndirectInputEvents
+
+
+
diff --git a/clone-instagram-login-Refactoring/ios/Runner/Runner-Bridging-Header.h b/clone-instagram-login-Refactoring/ios/Runner/Runner-Bridging-Header.h
new file mode 100644
index 0000000..308a2a5
--- /dev/null
+++ b/clone-instagram-login-Refactoring/ios/Runner/Runner-Bridging-Header.h
@@ -0,0 +1 @@
+#import "GeneratedPluginRegistrant.h"
diff --git a/clone-instagram-login-Refactoring/lib/app/data/models/navbar_menu.dart b/clone-instagram-login-Refactoring/lib/app/data/models/navbar_menu.dart
new file mode 100644
index 0000000..eba0bd9
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/data/models/navbar_menu.dart
@@ -0,0 +1,31 @@
+import 'package:flutter/material.dart';
+
+class NavbarMenu {
+ int? id;
+ String? name;
+ String? activeIcon;
+ String? inactiveIcon;
+ String? path;
+ Widget? widget;
+
+ NavbarMenu(
+ {this.id, this.name, this.activeIcon, this.inactiveIcon, this.path});
+
+ NavbarMenu.fromJson(Map json) {
+ id = json['id'];
+ name = json['name'];
+ activeIcon = json['active_icon'];
+ inactiveIcon = json['inactive_icon'];
+ path = json['path'];
+ }
+
+ Map toJson() {
+ final Map data = {};
+ data['id'] = id;
+ data['name'] = name;
+ data['active_icon'] = activeIcon;
+ data['inactive_icon'] = inactiveIcon;
+ data['path'] = path;
+ return data;
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/data/models/post.dart b/clone-instagram-login-Refactoring/lib/app/data/models/post.dart
new file mode 100644
index 0000000..f7f3f6f
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/data/models/post.dart
@@ -0,0 +1,48 @@
+class Post {
+ int? id;
+ String? name;
+ String? profileImg;
+ String? postImg;
+ String? caption;
+ bool? isLoved;
+ String? commentCount;
+ String? likedBy;
+ String? timeAgo;
+
+ Post(
+ {this.id,
+ this.name,
+ this.profileImg,
+ this.postImg,
+ this.caption,
+ this.isLoved,
+ this.commentCount,
+ this.likedBy,
+ this.timeAgo});
+
+ Post.fromJson(Map json) {
+ id = json['id'];
+ name = json['name'];
+ profileImg = json['profileImg'];
+ postImg = json['postImg'];
+ caption = json['caption'];
+ isLoved = json['isLoved'];
+ commentCount = json['commentCount'];
+ likedBy = json['likedBy'];
+ timeAgo = json['timeAgo'];
+ }
+
+ Map toJson() {
+ final Map data = {};
+ data['id'] = id;
+ data['name'] = name;
+ data['profileImg'] = profileImg;
+ data['postImg'] = postImg;
+ data['caption'] = caption;
+ data['isLoved'] = isLoved;
+ data['commentCount'] = commentCount;
+ data['likedBy'] = likedBy;
+ data['timeAgo'] = timeAgo;
+ return data;
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/data/models/profile.dart b/clone-instagram-login-Refactoring/lib/app/data/models/profile.dart
new file mode 100644
index 0000000..2ee7c58
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/data/models/profile.dart
@@ -0,0 +1,50 @@
+class Profile {
+ String? name;
+ String? bio;
+ String? profilePic;
+ List? stats;
+
+ Profile({this.name, this.bio, this.profilePic, this.stats});
+
+ Profile.fromJson(Map json) {
+ name = json['name'];
+ bio = json['bio'];
+ profilePic = json['profilePic'];
+ if (json['stats'] != null) {
+ stats = [];
+ json['stats'].forEach((v) {
+ stats!.add(Stats.fromJson(v));
+ });
+ }
+ }
+
+ Map toJson() {
+ final Map data = {};
+ data['name'] = name;
+ data['bio'] = bio;
+ data['profilePic'] = profilePic;
+ if (stats != null) {
+ data['stats'] = stats!.map((v) => v.toJson()).toList();
+ }
+ return data;
+ }
+}
+
+class Stats {
+ int? count;
+ String? label;
+
+ Stats({this.count, this.label});
+
+ Stats.fromJson(Map json) {
+ count = json['count'];
+ label = json['label'];
+ }
+
+ Map toJson() {
+ final Map data = {};
+ data['count'] = count;
+ data['label'] = label;
+ return data;
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/account/account_page.dart b/clone-instagram-login-Refactoring/lib/app/modules/account/account_page.dart
new file mode 100644
index 0000000..e80f4f5
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/account/account_page.dart
@@ -0,0 +1,116 @@
+import 'package:example_widget_testing/app/modules/account/components/account_name.dart';
+import 'package:example_widget_testing/app/modules/account/components/account_tab.dart';
+import 'package:example_widget_testing/app/modules/account/components/highlight_list.dart';
+import 'package:example_widget_testing/app/modules/account/components/profile_buttons.dart';
+import 'package:example_widget_testing/app/widgets/bottom_navbar.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+import '../../data/models/profile.dart';
+import '../../widgets/post_thumbnail.dart';
+import 'components/account_stat.dart';
+
+class AccountPage extends StatefulWidget {
+ const AccountPage(
+ {super.key,
+ required this.profileData,
+ required this.posts,
+ required this.stories});
+ final Map profileData;
+ final List posts;
+ final List stories;
+
+ @override
+ AccountPageState createState() => AccountPageState();
+}
+
+class AccountPageState extends State {
+ int pageIndex = 0;
+
+ void updateIndex(int index) {
+ setState(() => pageIndex = index);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final Profile profile = Profile.fromJson(widget.profileData);
+ return Scaffold(
+ backgroundColor: Colors.black,
+ appBar: AppBar(
+ key: const Key('app_bar_account'),
+ backgroundColor: Colors.black,
+ automaticallyImplyLeading: false,
+ title: Row(
+ key: const Key('app_bar_row'),
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Row(
+ key: const Key('app_bar_row_name'),
+ children: const [
+ Text(
+ key: Key('app_bar_row_name_text'),
+ "iclop",
+ style: TextStyle(fontWeight: FontWeight.bold),
+ ),
+ Icon(
+ key: Key('app_bar_row_name_arrow_down_icon'),
+ Icons.keyboard_arrow_down,
+ ),
+ ],
+ ),
+ Row(
+ key: const Key('app_bar_row_menu'),
+ children: [
+ SvgPicture.asset(
+ key: const Key('app_bar_row_menu_upload_icon'),
+ "assets/images/upload_icon.svg",
+ width: 27,
+ ),
+ const SizedBox(
+ width: 10,
+ ),
+ const Icon(
+ key: Key('app_bar_row_menu_hamburger_icon'),
+ Icons.menu,
+ size: 35,
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+ body: ListView(
+ key: const Key('account_page_listview'),
+ children: [
+ AccountStat(key: const Key("account_stat"), profile: profile),
+ AccountName(key: const Key("account_name"), profile: profile),
+ const ProfileButtons(key: Key("profile_buttons")),
+ HighlightList(
+ key: const Key("highlight_list"), stories: widget.stories),
+ AccountTab(
+ key: const Key("account_tab"),
+ updateIndex: updateIndex,
+ pageIndex: pageIndex,
+ ),
+ Wrap(
+ key: const Key('account_page_post_wrap'),
+ spacing: 1.5,
+ runSpacing: 1.5,
+ children: List.generate(widget.posts.length, (index) {
+ return InkWell(
+ key: Key("account_post_inkwell_$index"),
+ onTap: () {
+ Navigator.pushNamed(context, '/post');
+ },
+ child: PostThumbnail(
+ key: Key("account_post_thumbnail_$index"),
+ imageUrl: widget.posts[index]['postImg'],
+ ),
+ );
+ }),
+ )
+ ],
+ ),
+ bottomNavigationBar: const BottomNavbar(pageIndex: 4),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/account/components/account_name.dart b/clone-instagram-login-Refactoring/lib/app/modules/account/components/account_name.dart
new file mode 100644
index 0000000..f3a8fd5
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/account/components/account_name.dart
@@ -0,0 +1,42 @@
+import 'package:flutter/material.dart';
+
+import '../../../data/models/profile.dart';
+
+class AccountName extends StatelessWidget {
+ const AccountName({super.key, required this.profile});
+ final Profile profile;
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ key: const Key('account_name_container'),
+ width: double.infinity,
+ padding: const EdgeInsets.symmetric(horizontal: 15),
+ margin: const EdgeInsets.symmetric(vertical: 10),
+ child: Column(
+ key: const Key('account_name_column'),
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ key: const Key('account_name_text'),
+ profile.name!,
+ style: const TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.w400,
+ color: Colors.white,
+ ),
+ ),
+ Text(
+ key: const Key('account_bio_text'),
+ profile.bio!,
+ style: const TextStyle(
+ fontSize: 15,
+ fontWeight: FontWeight.w400,
+ color: Colors.white,
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/account/components/account_stat.dart b/clone-instagram-login-Refactoring/lib/app/modules/account/components/account_stat.dart
new file mode 100644
index 0000000..0db3a23
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/account/components/account_stat.dart
@@ -0,0 +1,31 @@
+import 'package:example_widget_testing/app/modules/account/components/profile_information.dart';
+import 'package:example_widget_testing/app/modules/account/components/profile_pic.dart';
+import 'package:flutter/widgets.dart';
+
+import '../../../data/models/profile.dart';
+
+class AccountStat extends StatelessWidget {
+ final Profile profile;
+
+ const AccountStat({super.key, required this.profile});
+
+ @override
+ Widget build(BuildContext context) {
+ return Row(
+ key: const Key('account_page_profile_row'),
+ children: [
+ ProfilePic(
+ key: const Key("profile_pic"),
+ pictureUrl: profile.profilePic!,
+ ),
+ Expanded(
+ key: const Key('account_page_profile_information_expanded'),
+ child: ProfileInformation(
+ key: const Key("profile_information"),
+ profileStats: profile.stats!,
+ ),
+ ),
+ ],
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/account/components/account_tab.dart b/clone-instagram-login-Refactoring/lib/app/modules/account/components/account_tab.dart
new file mode 100644
index 0000000..53b416c
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/account/components/account_tab.dart
@@ -0,0 +1,49 @@
+import 'package:flutter/material.dart';
+
+import '../../../../core/values/constant/profile_tabs_json.dart';
+
+class AccountTab extends StatelessWidget {
+ final Function(int index) updateIndex;
+ final int pageIndex;
+
+ const AccountTab(
+ {super.key, required this.updateIndex, required this.pageIndex});
+
+ @override
+ Widget build(BuildContext context) {
+ final size = MediaQuery.of(context).size;
+ return Row(
+ key: const Key("account_tab_row"),
+ children: List.generate(
+ tabs.length,
+ (index) {
+ return DecoratedBox(
+ key: Key('account_tab_decorated_box_$index'),
+ decoration: BoxDecoration(
+ border: Border(
+ bottom: BorderSide(
+ color: pageIndex == index ? Colors.white : Colors.transparent,
+ width: 2,
+ ),
+ ),
+ ),
+ child: ElevatedButton(
+ key: Key('account_tab_elevated_button_$index'),
+ onPressed: () => updateIndex(index),
+ style: ElevatedButton.styleFrom(
+ elevation: 0,
+ backgroundColor: Colors.transparent,
+ minimumSize: Size(size.width / tabs.length, 40),
+ ),
+ child: Icon(
+ tabs[index]['icon'],
+ key: Key('account_tab_icon_$index'),
+ color: Colors.white,
+ ),
+ ),
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/account/components/grey_button.dart b/clone-instagram-login-Refactoring/lib/app/modules/account/components/grey_button.dart
new file mode 100644
index 0000000..3b4c318
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/account/components/grey_button.dart
@@ -0,0 +1,23 @@
+import 'package:flutter/material.dart';
+
+class GreyButton extends StatelessWidget {
+ final Function onPressed;
+ final Widget child;
+
+ const GreyButton({super.key, required this.onPressed, required this.child});
+ @override
+ Widget build(BuildContext context) {
+ return ElevatedButton(
+ key: Key('${key}_elevated_button'),
+ onPressed: () => {},
+ style: ElevatedButton.styleFrom(
+ minimumSize: const Size(0, 30),
+ backgroundColor: Colors.grey[800],
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(5),
+ ),
+ ),
+ child: child,
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/account/components/highlight_item.dart b/clone-instagram-login-Refactoring/lib/app/modules/account/components/highlight_item.dart
new file mode 100644
index 0000000..0c6177a
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/account/components/highlight_item.dart
@@ -0,0 +1,58 @@
+import 'package:example_widget_testing/core/theme/colors.dart';
+import 'package:flutter/material.dart';
+
+class HighlightItem extends StatelessWidget {
+ final String img;
+ final String name;
+
+ const HighlightItem({super.key, required this.img, required this.name});
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ key: const Key('highlight_item_padding'),
+ padding: const EdgeInsets.only(right: 10, bottom: 10),
+ child: Column(
+ key: const Key('highlight_item_column'),
+ children: [
+ Container(
+ key: const Key('highlight_item_container'),
+ width: 68,
+ height: 68,
+ padding: const EdgeInsets.all(3.0),
+ margin: const EdgeInsets.only(bottom: 8),
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ border: Border.all(
+ color: (Colors.grey[800])!,
+ width: 1,
+ ),
+ ),
+ child: Container(
+ key: const Key('highlight_item_image_container'),
+ decoration: BoxDecoration(
+ border: Border.all(color: Colors.black, width: 2),
+ shape: BoxShape.circle,
+ image: DecorationImage(
+ image: NetworkImage(img),
+ fit: BoxFit.cover,
+ ),
+ ),
+ ),
+ ),
+ SizedBox(
+ key: const Key('highlight_item_text_sized_box'),
+ width: 70,
+ child: Text(
+ key: const Key('highlight_item_text'),
+ name,
+ overflow: TextOverflow.ellipsis,
+ style: const TextStyle(color: white),
+ textAlign: TextAlign.center,
+ ),
+ )
+ ],
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/account/components/highlight_list.dart b/clone-instagram-login-Refactoring/lib/app/modules/account/components/highlight_list.dart
new file mode 100644
index 0000000..eafecca
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/account/components/highlight_list.dart
@@ -0,0 +1,81 @@
+import 'package:example_widget_testing/app/modules/account/components/highlight_item.dart';
+import 'package:flutter/material.dart';
+
+class HighlightList extends StatelessWidget {
+ const HighlightList({super.key, required this.stories});
+ final List stories;
+
+ @override
+ Widget build(BuildContext context) {
+ return SingleChildScrollView(
+ key: const Key('highlight_list_scroll_view'),
+ padding: const EdgeInsets.only(left: 15, top: 10, bottom: 10),
+ scrollDirection: Axis.horizontal,
+ child: Row(
+ key: const Key('highlight_list_parent_row'),
+ children: [
+ Row(
+ key: const Key('highlight_list_child_row'),
+ children: List.generate(
+ stories.length,
+ (index) {
+ return HighlightItem(
+ key: Key('highlight_item_$index'),
+ img: stories[index]['img'],
+ name: stories[index]['name'],
+ );
+ },
+ ),
+ ),
+ Padding(
+ key: const Key('highlight_list_add_highlight'),
+ padding: const EdgeInsets.only(right: 10, bottom: 10),
+ child: Column(
+ key: const Key('highlight_list_add_highlight_column'),
+ children: [
+ Container(
+ key: const Key('highlight_list_add_highlight_container'),
+ width: 68,
+ height: 68,
+ padding: const EdgeInsets.all(3.0),
+ margin: const EdgeInsets.only(bottom: 8),
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ border: Border.all(
+ color: Colors.white,
+ width: 1,
+ ),
+ ),
+ child: Container(
+ key: const Key(
+ 'highlight_list_add_highlight_icon_container'),
+ decoration: BoxDecoration(
+ border: Border.all(color: Colors.black, width: 2),
+ shape: BoxShape.circle,
+ ),
+ child: const Icon(
+ key: Key('highlight_list_add_highlight_icon'),
+ Icons.add,
+ color: Colors.white,
+ ),
+ ),
+ ),
+ const SizedBox(
+ key: Key('highlight_list_add_highlight_text_sized_box'),
+ width: 70,
+ child: Text(
+ key: Key('highlight_list_add_highlight_text'),
+ 'New',
+ overflow: TextOverflow.ellipsis,
+ style: TextStyle(color: Colors.white),
+ textAlign: TextAlign.center,
+ ),
+ )
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/account/components/profile_buttons.dart b/clone-instagram-login-Refactoring/lib/app/modules/account/components/profile_buttons.dart
new file mode 100644
index 0000000..32c9322
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/account/components/profile_buttons.dart
@@ -0,0 +1,63 @@
+import 'package:example_widget_testing/app/modules/account/components/grey_button.dart';
+import 'package:flutter/material.dart';
+
+class ProfileButtons extends StatelessWidget {
+ const ProfileButtons({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ key: const Key('profile_buttons_padding'),
+ padding: const EdgeInsets.symmetric(horizontal: 15),
+ child: Row(
+ key: const Key('profile_buttons_row'),
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Expanded(
+ key: const Key('profile_buttons_edit_profile_button_expanded'),
+ child: GreyButton(
+ key: const Key('profile_buttons_edit_profile_button'),
+ onPressed: () {},
+ child: const Text(
+ key: Key('profile_buttons_edit_profile_button_text'),
+ "Edit Profile",
+ style: TextStyle(
+ fontSize: 15,
+ fontWeight: FontWeight.w500,
+ color: Colors.white,
+ ),
+ ),
+ ),
+ ),
+ const SizedBox(width: 5),
+ Expanded(
+ key: const Key('profile_buttons_share_profile_button_expanded'),
+ child: GreyButton(
+ key: const Key('profile_buttons_share_profile_button'),
+ onPressed: () {},
+ child: const Text(
+ key: Key('profile_buttons_share_profile_button_text'),
+ "Share profile",
+ style: TextStyle(
+ fontSize: 15,
+ fontWeight: FontWeight.w500,
+ color: Colors.white,
+ ),
+ ),
+ ),
+ ),
+ const SizedBox(width: 5),
+ GreyButton(
+ key: const Key('profile_buttons_discover_people_button'),
+ onPressed: () {},
+ child: const Icon(
+ key: Key("profile_buttons_discover_people_icon"),
+ Icons.person_add_outlined,
+ color: Colors.white,
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/account/components/profile_information.dart b/clone-instagram-login-Refactoring/lib/app/modules/account/components/profile_information.dart
new file mode 100644
index 0000000..c2e769f
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/account/components/profile_information.dart
@@ -0,0 +1,43 @@
+import 'package:example_widget_testing/app/data/models/profile.dart';
+import 'package:flutter/material.dart';
+
+class ProfileInformation extends StatelessWidget {
+ const ProfileInformation({super.key, required this.profileStats});
+ final List profileStats;
+
+ @override
+ Widget build(BuildContext context) {
+ return Row(
+ key: const Key('profile_information_row'),
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
+ children: List.generate(
+ profileStats.length,
+ (index) {
+ return Column(
+ key: Key('profile_information_column_$index'),
+ children: [
+ Text(
+ key: Key('profile_information_${index}_amount_text'),
+ profileStats[index].count.toString(),
+ style: const TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.w700,
+ color: Colors.white,
+ ),
+ ),
+ Text(
+ profileStats[index].label!,
+ key: Key('profile_information_${index}_label_text'),
+ style: const TextStyle(
+ fontSize: 15,
+ fontWeight: FontWeight.w400,
+ color: Colors.white,
+ ),
+ ),
+ ],
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/account/components/profile_pic.dart b/clone-instagram-login-Refactoring/lib/app/modules/account/components/profile_pic.dart
new file mode 100644
index 0000000..c7fa599
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/account/components/profile_pic.dart
@@ -0,0 +1,23 @@
+import 'package:flutter/material.dart';
+
+class ProfilePic extends StatelessWidget {
+ const ProfilePic({super.key, required this.pictureUrl});
+ final String pictureUrl;
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ key: const Key('profile_pic_container'),
+ width: 80,
+ height: 80,
+ margin: const EdgeInsets.only(left: 15, right: 30),
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ image: DecorationImage(
+ image: NetworkImage(pictureUrl),
+ fit: BoxFit.cover,
+ ),
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/account/components/tab_delegate.dart b/clone-instagram-login-Refactoring/lib/app/modules/account/components/tab_delegate.dart
new file mode 100644
index 0000000..00495e1
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/account/components/tab_delegate.dart
@@ -0,0 +1,32 @@
+import 'package:flutter/material.dart';
+
+class MyPersistentHeaderDelegate extends SliverPersistentHeaderDelegate {
+ final double height;
+ final Widget child;
+
+ MyPersistentHeaderDelegate({
+ required this.height,
+ required this.child,
+ });
+
+ @override
+ Widget build(
+ BuildContext context, double shrinkOffset, bool overlapsContent) {
+ return Container(
+ color: Colors.white, // Set the background color of the header
+ height: height,
+ child: child,
+ );
+ }
+
+ @override
+ double get maxExtent => height;
+
+ @override
+ double get minExtent => height;
+
+ @override
+ bool shouldRebuild(covariant MyPersistentHeaderDelegate oldDelegate) {
+ return height != oldDelegate.height || child != oldDelegate.child;
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/activity/activity_page.dart b/clone-instagram-login-Refactoring/lib/app/modules/activity/activity_page.dart
new file mode 100644
index 0000000..bb4cad5
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/activity/activity_page.dart
@@ -0,0 +1,40 @@
+import 'package:example_widget_testing/app/widgets/bottom_navbar.dart';
+import 'package:flutter/material.dart';
+
+class ActivityPage extends StatelessWidget {
+ const ActivityPage({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ backgroundColor: Colors.black,
+ appBar: AppBar(
+ key: const Key("activity_page_appbar"),
+ backgroundColor: Colors.black,
+ title: const Text("Activity"),
+ ),
+ body: Center(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: const [
+ Icon(
+ Icons.favorite_border,
+ color: Colors.white,
+ size: 100.0,
+ ),
+ SizedBox(height: 20.0),
+ Text(
+ "No Activity",
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ color: Colors.white,
+ ),
+ ),
+ ],
+ ),
+ ),
+ bottomNavigationBar: const BottomNavbar(pageIndex: 3),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/calculator.dart b/clone-instagram-login-Refactoring/lib/app/modules/calculator.dart
new file mode 100644
index 0000000..2d9845f
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/calculator.dart
@@ -0,0 +1,66 @@
+import 'package:flutter/material.dart';
+
+class SimpleCalculator extends StatefulWidget {
+ const SimpleCalculator({Key? key}) : super(key: key);
+
+ @override
+ State createState() => SimpleCalculatorState();
+}
+
+class SimpleCalculatorState extends State {
+ TextEditingController variableA = TextEditingController();
+ TextEditingController variableB = TextEditingController();
+ String result = '0';
+
+ void add() {
+ setState(() {
+ result =
+ (int.parse(variableA.text) + int.parse(variableB.text)).toString();
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(title: const Text('Simple Calculator')),
+ body: Padding(
+ padding: const EdgeInsets.all(10),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ TextField(
+ key: const Key('variableA'),
+ style: const TextStyle(color: Colors.black),
+ decoration: const InputDecoration(
+ border: OutlineInputBorder(),
+ ),
+ controller: variableA,
+ keyboardType: TextInputType.number,
+ ),
+ const SizedBox(height: 10),
+ TextField(
+ key: const Key('variableB'),
+ // add border
+ style: const TextStyle(color: Colors.black),
+ decoration: const InputDecoration(
+ border: OutlineInputBorder(),
+ ),
+ controller: variableB,
+ keyboardType: TextInputType.number,
+ ),
+ ElevatedButton(
+ key: const Key('addButton'),
+ onPressed: () => add(),
+ child: const Text('Add'),
+ ),
+ Text(
+ key: const Key('result'),
+ result,
+ style: const TextStyle(fontSize: 35),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/home/components/story_item.dart b/clone-instagram-login-Refactoring/lib/app/modules/home/components/story_item.dart
new file mode 100644
index 0000000..287ad74
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/home/components/story_item.dart
@@ -0,0 +1,63 @@
+import 'package:example_widget_testing/core/theme/colors.dart';
+import 'package:flutter/material.dart';
+
+class StoryItem extends StatelessWidget {
+ final String img;
+ final String name;
+
+ const StoryItem({
+ super.key,
+ required this.img,
+ required this.name,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ key: const Key('story_item_padding'),
+ padding: const EdgeInsets.only(right: 20, bottom: 10),
+ child: Column(
+ key: const Key('story_item_column'),
+ children: [
+ Container(
+ key: const Key('story_item_container'),
+ width: 68,
+ height: 68,
+ margin: const EdgeInsets.only(bottom: 8),
+ decoration: const BoxDecoration(
+ shape: BoxShape.circle,
+ gradient: LinearGradient(
+ begin: Alignment.topCenter,
+ end: Alignment.bottomCenter,
+ colors: storyBorderColor),
+ ),
+ child: Container(
+ key: const Key('story_item_image_container'),
+ margin: const EdgeInsets.all(3),
+ width: 65,
+ height: 65,
+ decoration: BoxDecoration(
+ border: Border.all(color: black, width: 2),
+ shape: BoxShape.circle,
+ image: DecorationImage(
+ image: NetworkImage(img),
+ fit: BoxFit.cover,
+ ),
+ ),
+ ),
+ ),
+ SizedBox(
+ key: const Key('story_item_username_sizedbox'),
+ width: 70,
+ child: Text(
+ name,
+ key: const Key('story_item_username_text'),
+ overflow: TextOverflow.ellipsis,
+ style: const TextStyle(color: white),
+ ),
+ )
+ ],
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/home/components/user_story.dart b/clone-instagram-login-Refactoring/lib/app/modules/home/components/user_story.dart
new file mode 100644
index 0000000..de68441
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/home/components/user_story.dart
@@ -0,0 +1,76 @@
+import 'package:example_widget_testing/core/theme/colors.dart';
+import 'package:example_widget_testing/core/values/constant/story_json.dart';
+import 'package:flutter/material.dart';
+
+class UserStory extends StatelessWidget {
+ const UserStory({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ key: const Key('user_story_padding'),
+ padding: const EdgeInsets.only(right: 20, left: 15, bottom: 10),
+ child: Column(
+ key: const Key('user_story_column'),
+ children: [
+ SizedBox(
+ key: const Key('user_story_sized_box'),
+ width: 65,
+ height: 65,
+ child: Stack(
+ key: const Key('user_story_stack'),
+ children: [
+ Container(
+ key: const Key('user_story_container'),
+ width: 65,
+ height: 65,
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ image: DecorationImage(
+ image: NetworkImage(profile),
+ fit: BoxFit.cover,
+ ),
+ ),
+ ),
+ Positioned(
+ key: const Key('user_story_positioned'),
+ bottom: 0,
+ right: 0,
+ child: Container(
+ key: const Key('user_story_outline_container'),
+ width: 19,
+ height: 19,
+ decoration: const BoxDecoration(
+ shape: BoxShape.circle,
+ color: Colors.white,
+ ),
+ child: const Icon(
+ key: Key('user_story_add_circle_icon'),
+ Icons.add_circle,
+ color: buttonFollowColor,
+ size: 19,
+ ),
+ ),
+ )
+ ],
+ ),
+ ),
+ const SizedBox(
+ key: Key('user_story_sized_box_spacer'),
+ height: 8,
+ ),
+ SizedBox(
+ key: const Key('user_story_sized_box_name'),
+ width: 70,
+ child: Text(
+ key: const Key('user_story_text_name'),
+ name,
+ overflow: TextOverflow.ellipsis,
+ style: const TextStyle(color: Colors.white),
+ ),
+ )
+ ],
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/home/home_page.dart b/clone-instagram-login-Refactoring/lib/app/modules/home/home_page.dart
new file mode 100644
index 0000000..0a903a8
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/home/home_page.dart
@@ -0,0 +1,126 @@
+import 'package:example_widget_testing/app/modules/home/components/user_story.dart';
+import 'package:example_widget_testing/app/widgets/post_item.dart';
+import 'package:example_widget_testing/app/modules/home/components/story_item.dart';
+import 'package:flutter/material.dart';
+
+import '../../../core/theme/colors.dart';
+import '../../data/models/profile.dart';
+import '../../widgets/bottom_navbar.dart';
+
+class HomePage extends StatefulWidget {
+ const HomePage({
+ super.key,
+ required this.posts,
+ required this.stories,
+ required this.profileData,
+ });
+ final List posts;
+ final List stories;
+ final Map profileData;
+
+ @override
+ HomePageState createState() => HomePageState();
+}
+
+class HomePageState extends State {
+ List posts = [];
+ @override
+ void initState() {
+ super.initState();
+ posts = widget.posts;
+ }
+
+ void updatePostLike(index) {
+ setState(() {
+ posts[index]['isLoved'] = !posts[index]['isLoved'];
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final Profile profile = Profile.fromJson(widget.profileData);
+ return Scaffold(
+ key: const Key('home_page_scaffold'),
+ backgroundColor: Colors.black,
+ appBar: AppBar(
+ key: const Key("home_page_appbar"),
+ backgroundColor: Colors.black,
+ leading: const Icon(
+ key: Key('home_page_camera_icon'),
+ Icons.camera_alt,
+ ),
+ title: const Center(
+ key: Key('home_page_title_center'),
+ child: Text(
+ key: Key('home_page_title_text'),
+ "Instagram",
+ style: TextStyle(fontFamily: 'Billabong', fontSize: 35),
+ ),
+ ),
+ actions: const [
+ Icon(key: Key('home_page_send_icon'), Icons.send),
+ ],
+ ),
+ body: SingleChildScrollView(
+ key: const Key('home_page_single_child_scroll_view'),
+ child: Column(
+ key: const Key('home_page_column'),
+ children: [
+ SingleChildScrollView(
+ key: const Key('stories_scroll_view'),
+ scrollDirection: Axis.horizontal,
+ child: Row(
+ key: const Key('stories_row'),
+ children: [
+ const UserStory(key: Key('user_story')),
+ Row(
+ key: const Key('following_stories_row'),
+ children: List.generate(
+ widget.stories.length,
+ (index) {
+ return StoryItem(
+ key: Key('story_item_$index'),
+ img: widget.stories[index]['img'],
+ name: widget.stories[index]['name'],
+ );
+ },
+ ),
+ ),
+ ],
+ ),
+ ),
+ Divider(
+ key: const Key('home_page_divider'),
+ color: white.withOpacity(0.3),
+ ),
+ Column(
+ key: const Key('posts_column'),
+ children: List.generate(
+ widget.posts.length,
+ (index) {
+ return PostItem(
+ key: Key('post_item_$index'),
+ postImg: posts[index]['postImg'],
+ profileImg: posts[index]['profileImg'],
+ name: posts[index]['name'],
+ caption: posts[index]['caption'],
+ isLoved: posts[index]['isLoved'],
+ viewCount: posts[index]['commentCount'],
+ likedBy: posts[index]['likedBy'],
+ dayAgo: posts[index]['timeAgo'],
+ userPhoto: profile.profilePic!,
+ onPressed: () => updatePostLike(index),
+ );
+ },
+ ),
+ )
+ ],
+ ),
+ ),
+ bottomNavigationBar: const BottomNavbar(
+ key: Key('home_page_bottom_navbar'),
+ pageIndex: 0,
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/login/components/facebook_login.dart b/clone-instagram-login-Refactoring/lib/app/modules/login/components/facebook_login.dart
new file mode 100644
index 0000000..63ad0d5
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/login/components/facebook_login.dart
@@ -0,0 +1,30 @@
+import 'package:flutter/material.dart';
+
+class FacebookLogin extends StatelessWidget {
+ final double width;
+ const FacebookLogin({super.key, required this.width});
+ @override
+ Widget build(BuildContext context) {
+ return Row(
+ key: const Key('facebook_login'),
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Image.asset(
+ 'assets/facebook.png',
+ height: width * .060,
+ key: const Key('facebook_logo'),
+ ),
+ const SizedBox(width: 5),
+ Text(
+ 'Login with facebook',
+ key: const Key('facebook_login_text'),
+ style: TextStyle(
+ color: const Color(0xff1877f2),
+ fontSize: width * .040,
+ fontWeight: FontWeight.w800,
+ ),
+ ),
+ ],
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/login/components/forgot_access.dart b/clone-instagram-login-Refactoring/lib/app/modules/login/components/forgot_access.dart
new file mode 100644
index 0000000..8cd99e0
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/login/components/forgot_access.dart
@@ -0,0 +1,40 @@
+import 'package:flutter/material.dart';
+
+class ForgotAccess extends StatelessWidget {
+ final double width;
+ const ForgotAccess({super.key, required this.width});
+
+ @override
+ Widget build(BuildContext context) {
+ return Row(
+ key: const Key('forgot_access_row'),
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ const Text(
+ 'Forgot your login details? ',
+ style: TextStyle(
+ fontSize: 13,
+ fontWeight: FontWeight.normal,
+ color: Colors.black,
+ ),
+ key: Key('forgot_access_text'),
+ ),
+ GestureDetector(
+ key: const Key('get_help_gesture_detector'),
+ onTap: () {
+ debugPrint('Get help');
+ },
+ child: const Text(
+ 'Get help',
+ style: TextStyle(
+ fontSize: 13,
+ color: Color(0xff002588),
+ fontWeight: FontWeight.bold,
+ ),
+ key: Key('get_help_text'),
+ ),
+ ),
+ ],
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/login/components/language_dropdown.dart b/clone-instagram-login-Refactoring/lib/app/modules/login/components/language_dropdown.dart
new file mode 100644
index 0000000..c885717
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/login/components/language_dropdown.dart
@@ -0,0 +1,38 @@
+import 'package:flutter/material.dart';
+
+class LanguageDropdown extends StatefulWidget {
+ const LanguageDropdown({super.key});
+
+ @override
+ LanguageDropdownState createState() => LanguageDropdownState();
+}
+
+class LanguageDropdownState extends State {
+ String dropdownValue = 'English';
+ final List languages = ['English', 'Arabic', 'Italian', 'French'];
+ @override
+ Widget build(BuildContext context) {
+ return DropdownButton(
+ key: const Key('language_dropdown'),
+ dropdownColor: Colors.white,
+ value: dropdownValue,
+ icon: const Icon(Icons.arrow_drop_down),
+ iconSize: 24,
+ elevation: 10,
+ style: const TextStyle(color: Colors.black54),
+ underline: Container(),
+ onChanged: (String? newValue) =>
+ setState(() => dropdownValue = newValue!),
+ items: languages.map>((String value) {
+ return DropdownMenuItem(
+ key: Key('language_dropdown_item_$value'),
+ value: value,
+ child: Text(
+ value,
+ style: const TextStyle(fontSize: 16),
+ ),
+ );
+ }).toList(),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/login/components/login_button.dart b/clone-instagram-login-Refactoring/lib/app/modules/login/components/login_button.dart
new file mode 100644
index 0000000..c6fb3b1
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/login/components/login_button.dart
@@ -0,0 +1,41 @@
+import 'package:flutter/material.dart';
+
+class LoginButton extends StatelessWidget {
+ final double width;
+ final bool inputTextNotNull;
+ final VoidCallback onPressed;
+
+ const LoginButton({
+ super.key,
+ required this.width,
+ required this.inputTextNotNull,
+ required this.onPressed,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return SizedBox(
+ key: const Key('login_button_sized_box'),
+ width: width * .90,
+ height: width * .14,
+ child: ElevatedButton(
+ key: const Key('login_button_elevated_button'),
+ onPressed: onPressed,
+ style: ElevatedButton.styleFrom(
+ backgroundColor: inputTextNotNull
+ ? const Color(0xff26A9FF)
+ : const Color(0xff78C9FF),
+ ),
+ child: Text(
+ key: const Key('login_button_text'),
+ 'Log In',
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: width * .040,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/login/components/or_divider.dart b/clone-instagram-login-Refactoring/lib/app/modules/login/components/or_divider.dart
new file mode 100644
index 0000000..05b16cb
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/login/components/or_divider.dart
@@ -0,0 +1,40 @@
+import 'package:flutter/material.dart';
+
+class ORDivider extends StatelessWidget {
+ final double width;
+ const ORDivider({super.key, required this.width});
+ @override
+ Widget build(BuildContext context) {
+ return Row(
+ key: const Key('or_divider_row'),
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Container(
+ key: const Key('or_divider_container_left'),
+ height: 1,
+ width: width * .40,
+ color: const Color(0xffA2A2A2),
+ ),
+ const SizedBox(
+ width: 10,
+ ),
+ Text(
+ key: const Key('or_divider_text'),
+ 'OR',
+ style: TextStyle(
+ fontSize: width * .040,
+ ),
+ ),
+ const SizedBox(
+ width: 10,
+ ),
+ Container(
+ key: const Key('or_divider_container_right'),
+ height: 1,
+ width: width * .40,
+ color: const Color(0xffA2A2A2),
+ ),
+ ],
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/login/components/password_textbox.dart b/clone-instagram-login-Refactoring/lib/app/modules/login/components/password_textbox.dart
new file mode 100644
index 0000000..6ef86dd
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/login/components/password_textbox.dart
@@ -0,0 +1,46 @@
+import 'package:flutter/material.dart';
+
+class PasswordTextbox extends StatelessWidget {
+ const PasswordTextbox({
+ super.key,
+ required this.width,
+ required this.checkInputNotNull,
+ required this.passwordController,
+ });
+
+ final double width;
+ final TextEditingController passwordController;
+ final VoidCallback checkInputNotNull;
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ key: const Key('password_textbox_container'),
+ width: width * .90,
+ height: width * .14,
+ decoration: const BoxDecoration(
+ color: Color(0xffE8E8E8),
+ borderRadius: BorderRadius.all(Radius.circular(5)),
+ ),
+ child: Padding(
+ key: const Key('password_textbox_padding'),
+ padding: const EdgeInsets.symmetric(horizontal: 15),
+ child: Center(
+ child: TextField(
+ key: const Key('password_textfield'),
+ onChanged: (text) {
+ checkInputNotNull();
+ },
+ controller: passwordController,
+ obscureText: true,
+ style: const TextStyle(
+ fontSize: 15,
+ ),
+ decoration: const InputDecoration.collapsed(
+ hintText: 'Password',
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/login/components/signup_section.dart b/clone-instagram-login-Refactoring/lib/app/modules/login/components/signup_section.dart
new file mode 100644
index 0000000..bea18a1
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/login/components/signup_section.dart
@@ -0,0 +1,47 @@
+import 'package:flutter/material.dart';
+
+class SignupSection extends StatelessWidget {
+ final double width;
+
+ const SignupSection({super.key, required this.width});
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ key: const Key('signup_section_column'),
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Container(
+ key: const Key('signup_section_container'),
+ width: width,
+ height: 1,
+ color: const Color(0xffA2A2A2),
+ ),
+ const SizedBox(height: 5),
+ Row(
+ key: const Key('signup_section'),
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(
+ "Don't have an account? ",
+ key: const Key('signup_section_text'),
+ style: TextStyle(fontSize: width * .040),
+ ),
+ TextButton(
+ key: const Key('signup_section_button'),
+ child: Text(
+ 'Sign up',
+ style: TextStyle(
+ color: const Color(0xff00258B),
+ fontSize: width * .040,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ onPressed: () => debugPrint('Sign Up'),
+ ),
+ ],
+ ),
+ ],
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/login/components/username_textbox.dart b/clone-instagram-login-Refactoring/lib/app/modules/login/components/username_textbox.dart
new file mode 100644
index 0000000..6274589
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/login/components/username_textbox.dart
@@ -0,0 +1,49 @@
+import 'package:flutter/material.dart';
+
+class UsernameTextbox extends StatelessWidget {
+ const UsernameTextbox({
+ super.key,
+ required this.width,
+ required this.checkInputNotNull,
+ required this.usernameController,
+ });
+
+ final double width;
+ final TextEditingController usernameController;
+ final VoidCallback checkInputNotNull;
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ key: const Key('username_textbox_container'),
+ width: width * .90,
+ height: width * .14,
+ decoration: const BoxDecoration(
+ color: Color(0xffE8E8E8),
+ borderRadius: BorderRadius.all(
+ Radius.circular(5),
+ ),
+ ),
+ child: Padding(
+ key: const Key('username_textbox_padding'),
+ padding: const EdgeInsets.symmetric(horizontal: 15),
+ child: Center(
+ key: const Key('username_textbox_center'),
+ child: TextField(
+ key: const Key('username_textfield'),
+ onChanged: (text) {
+ checkInputNotNull();
+ },
+ controller: usernameController,
+ style: const TextStyle(
+ fontSize: 15,
+ ),
+ decoration: const InputDecoration.collapsed(
+ hintText: 'Phone number , email or username',
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/login/login_page.dart b/clone-instagram-login-Refactoring/lib/app/modules/login/login_page.dart
new file mode 100644
index 0000000..22457f8
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/login/login_page.dart
@@ -0,0 +1,133 @@
+import 'components/facebook_login.dart';
+import 'components/forgot_access.dart';
+import 'components/or_divider.dart';
+import 'components/signup_section.dart';
+import 'components/login_button.dart';
+import 'components/password_textbox.dart';
+import 'package:flutter/material.dart';
+
+import 'components/language_dropdown.dart';
+import 'components/username_textbox.dart';
+
+class LoginPage extends StatefulWidget {
+ const LoginPage({super.key});
+
+ @override
+ LoginPageState createState() => LoginPageState();
+}
+
+class LoginPageState extends State {
+ TextEditingController usernameController = TextEditingController();
+ TextEditingController passwordController = TextEditingController();
+
+ bool inputTextNotNull = false;
+
+ void checkInputNotNull() {
+ setState(() {
+ if (usernameController.text.length >= 2 &&
+ passwordController.text.length >= 2) {
+ inputTextNotNull = true;
+ } else {
+ inputTextNotNull = false;
+ }
+ });
+ }
+
+ void openHomePage() {
+ inputTextNotNull ? Navigator.pushNamed(context, '/home') : null;
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final width = MediaQuery.of(context).size.width;
+ final height = MediaQuery.of(context).size.height;
+
+ double getAvailableHeight() {
+ return height -
+ MediaQuery.of(context).padding.top -
+ MediaQuery.of(context).padding.bottom;
+ }
+
+ return Scaffold(
+ key: const Key('login_page_scaffold'),
+ body: SafeArea(
+ key: const Key('login_page_safe_area'),
+ child: SingleChildScrollView(
+ key: const Key('login_page_scroll_view'),
+ child: ConstrainedBox(
+ key: const Key('login_page_constrained_box'),
+ constraints: BoxConstraints(minHeight: getAvailableHeight()),
+ child: Column(
+ key: const Key('login_page_column'),
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Container(
+ key: const Key('login_page_language_dropdown_container'),
+ width: width,
+ alignment: Alignment.topCenter,
+ child: const LanguageDropdown(),
+ ),
+ Column(
+ key: const Key('login_page_content_column'),
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Image.asset(
+ key: const Key('login_page_instagram_logo'),
+ 'assets/instagram_logo.png',
+ width: width * .5,
+ ),
+ const SizedBox(height: 15),
+ UsernameTextbox(
+ key: const Key('login_page_username_textbox'),
+ width: width,
+ checkInputNotNull: checkInputNotNull,
+ usernameController: usernameController,
+ ),
+ const SizedBox(height: 10),
+ PasswordTextbox(
+ key: const Key('login_page_password_textbox'),
+ width: width,
+ checkInputNotNull: checkInputNotNull,
+ passwordController: passwordController),
+ const SizedBox(height: 10),
+ LoginButton(
+ key: const Key('login_page_login_button'),
+ width: width,
+ inputTextNotNull: inputTextNotNull,
+ onPressed: () {
+ openHomePage();
+ },
+ ),
+ const SizedBox(
+ height: 15,
+ ),
+ ForgotAccess(
+ key: const Key('login_page_forgot_access'),
+ width: width,
+ ),
+ const SizedBox(height: 15),
+ ORDivider(
+ key: const Key('login_page_or_divider'),
+ width: width,
+ ),
+ const SizedBox(
+ height: 20,
+ ),
+ FacebookLogin(
+ key: const Key('login_page_facebook_login'),
+ width: width,
+ ),
+ ],
+ ),
+ SignupSection(
+ key: const Key('login_page_signup_section'),
+ width: width,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/post/post_page.dart b/clone-instagram-login-Refactoring/lib/app/modules/post/post_page.dart
new file mode 100644
index 0000000..57232eb
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/post/post_page.dart
@@ -0,0 +1,76 @@
+import 'package:example_widget_testing/app/widgets/bottom_navbar.dart';
+import 'package:example_widget_testing/app/widgets/post_item.dart';
+import 'package:example_widget_testing/core/values/constant/post_json.dart';
+import 'package:example_widget_testing/core/values/constant/story_json.dart';
+import 'package:flutter/material.dart';
+
+import '../../data/models/post.dart';
+
+class PostPage extends StatefulWidget {
+ final List posts;
+ const PostPage({super.key, required this.posts});
+
+ @override
+ PostPageState createState() => PostPageState();
+}
+
+class PostPageState extends State {
+ final List listPost = posts.map((e) => Post.fromJson(e)).toList();
+ void updatePostLike(id) {
+ setState(() {
+ for (var element in listPost) {
+ if (element.id == id) {
+ element.isLoved = !element.isLoved!;
+ }
+ }
+ });
+ }
+
+ @override
+ void initState() {
+ super.initState();
+ posts = widget.posts;
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ key: const Key('post_page_scaffold'),
+ backgroundColor: Colors.black,
+ appBar: AppBar(
+ backgroundColor: Colors.black,
+ title: const Text("Post"),
+ ),
+ body: SingleChildScrollView(
+ key: const Key('post_page_single_child_scroll_view'),
+ child: Column(
+ key: const Key('post_page_column'),
+ children: [
+ Column(
+ key: const Key('post_page_column'),
+ children: listPost.map((post) {
+ return PostItem(
+ key: Key('post_item_${post.id}'), // add key for testing
+ postImg: post.postImg!,
+ profileImg: post.profileImg!,
+ name: post.name!,
+ caption: post.caption!,
+ isLoved: post.isLoved!,
+ viewCount: post.commentCount!,
+ likedBy: post.likedBy!,
+ dayAgo: post.timeAgo!,
+ userPhoto: profile,
+ onPressed: () => updatePostLike(post.id!),
+ );
+ }).toList(),
+ )
+ ],
+ ),
+ ),
+ bottomNavigationBar: const BottomNavbar(
+ key: Key('post_page_bottom_navbar'),
+ pageIndex: 4,
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/search/components/search_category_item.dart b/clone-instagram-login-Refactoring/lib/app/modules/search/components/search_category_item.dart
new file mode 100644
index 0000000..c867bfc
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/search/components/search_category_item.dart
@@ -0,0 +1,30 @@
+// import 'package:example_widget_testing/core/theme/colors.dart';
+// import 'package:flutter/material.dart';
+
+// class CategoryStoryItem extends StatelessWidget {
+// final String name;
+
+// const CategoryStoryItem({super.key, required this.name});
+
+// @override
+// Widget build(BuildContext context) {
+// return Padding(
+// padding: const EdgeInsets.only(right: 10),
+// child: Container(
+// decoration: BoxDecoration(
+// borderRadius: BorderRadius.circular(10),
+// color: black,
+// border: Border.all(color: white.withOpacity(0.2))),
+// child: Padding(
+// padding:
+// const EdgeInsets.only(left: 20, right: 25, top: 10, bottom: 10),
+// child: Text(
+// name,
+// style: const TextStyle(
+// color: white, fontWeight: FontWeight.w500, fontSize: 15),
+// ),
+// ),
+// ),
+// );
+// }
+// }
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/search/search_list_page.dart b/clone-instagram-login-Refactoring/lib/app/modules/search/search_list_page.dart
new file mode 100644
index 0000000..73012fd
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/search/search_list_page.dart
@@ -0,0 +1,43 @@
+// import 'package:example_widget_testing/core/theme/colors.dart';
+// import 'package:flutter/material.dart';
+
+// class SearchListPage extends StatefulWidget {
+// const SearchListPage({super.key});
+
+// @override
+// SearchListPageState createState() => SearchListPageState();
+// }
+
+// class SearchListPageState extends State {
+// @override
+// Widget build(BuildContext context) {
+// return getBody();
+// }
+
+// Widget getBody() {
+// var size = MediaQuery.of(context).size;
+// return ListView(
+// children: [
+// Container(
+// margin: const EdgeInsets.only(bottom: 15, left: 15, right: 15),
+// width: size.width - 30,
+// height: 45,
+// decoration: BoxDecoration(
+// borderRadius: BorderRadius.circular(10),
+// color: textFieldBackground),
+// child: TextField(
+// decoration: InputDecoration(
+// border: InputBorder.none,
+// prefixIcon: Icon(
+// Icons.search,
+// color: white.withOpacity(0.3),
+// ),
+// ),
+// style: TextStyle(color: white.withOpacity(0.3)),
+// cursorColor: white.withOpacity(0.3),
+// ),
+// ),
+// ],
+// );
+// }
+// }
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/search/search_page.dart b/clone-instagram-login-Refactoring/lib/app/modules/search/search_page.dart
new file mode 100644
index 0000000..51a1149
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/search/search_page.dart
@@ -0,0 +1,73 @@
+import 'package:example_widget_testing/app/widgets/bottom_navbar.dart';
+import 'package:example_widget_testing/core/theme/colors.dart';
+// import 'package:example_widget_testing/core/values/constant/search_json.dart';
+import 'package:flutter/material.dart';
+
+import '../../widgets/post_thumbnail.dart';
+
+class SearchPage extends StatefulWidget {
+ const SearchPage({super.key, required this.searchPosts});
+ final List searchPosts;
+
+ @override
+ SearchPageState createState() => SearchPageState();
+}
+
+class SearchPageState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ key: const Key('search_page_scaffold'),
+ backgroundColor: Colors.black,
+ appBar: const PreferredSize(
+ key: Key('search_page_app_bar_preferred_size'),
+ preferredSize: Size.fromHeight(0),
+ child: SizedBox(
+ height: 20,
+ ),
+ ),
+ body: ListView(
+ key: const Key('search_page_listview'),
+ children: [
+ Container(
+ key: const Key('search_page_textfield_container'),
+ margin: const EdgeInsets.only(bottom: 15, left: 15, right: 15),
+ height: 45,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(10),
+ color: textFieldBackground),
+ child: TextField(
+ key: const Key('search_page_textfield'),
+ onTap: () {
+ debugPrint('clicked');
+ },
+ decoration: InputDecoration(
+ border: InputBorder.none,
+ prefixIcon: Icon(
+ Icons.search,
+ color: white.withOpacity(0.3),
+ ),
+ ),
+ style: TextStyle(color: white.withOpacity(0.3)),
+ cursorColor: white.withOpacity(0.3),
+ ),
+ ),
+ Wrap(
+ key: const Key('search_page_wrap'),
+ spacing: 1,
+ runSpacing: 1,
+ children: widget.searchPosts.map((imageUrl) {
+ return PostThumbnail(
+ imageUrl: imageUrl,
+ );
+ }).toList(),
+ )
+ ],
+ ),
+ bottomNavigationBar: const BottomNavbar(
+ key: Key('search_page_bottom_navbar'),
+ pageIndex: 1,
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/modules/upload/upload_page.dart b/clone-instagram-login-Refactoring/lib/app/modules/upload/upload_page.dart
new file mode 100644
index 0000000..1f40e79
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/modules/upload/upload_page.dart
@@ -0,0 +1,40 @@
+import 'package:example_widget_testing/app/widgets/bottom_navbar.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+
+class UploadPage extends StatelessWidget {
+ const UploadPage({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ backgroundColor: Colors.black,
+ appBar: AppBar(
+ key: const Key("upload_page_appbar"),
+ backgroundColor: Colors.black,
+ title: const Text("Upload"),
+ ),
+ body: Center(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ SvgPicture.asset(
+ "assets/images/upload_icon.svg",
+ width: 60,
+ ),
+ const SizedBox(height: 20.0),
+ const Text(
+ "Upload Page",
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ color: Colors.white,
+ ),
+ ),
+ ],
+ ),
+ ),
+ bottomNavigationBar: const BottomNavbar(pageIndex: 2),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/widgets/bottom_navbar.dart b/clone-instagram-login-Refactoring/lib/app/widgets/bottom_navbar.dart
new file mode 100644
index 0000000..e80c884
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/widgets/bottom_navbar.dart
@@ -0,0 +1,41 @@
+import 'package:example_widget_testing/core/values/constant/navbarmenu_json.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+
+class BottomNavbar extends StatelessWidget {
+ final int pageIndex;
+ const BottomNavbar({super.key, required this.pageIndex});
+
+ @override
+ Widget build(BuildContext context) {
+ void navigateToPage(int index) {
+ Navigator.pushNamed(context, navbarMenuList[index].path!);
+ }
+
+ return Container(
+ key: const Key("bottom_navigation_bar_container"),
+ width: double.infinity,
+ height: 55,
+ color: Colors.black,
+ padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20, top: 15),
+ child: Row(
+ key: const Key("bottom_navigation_bar_row"),
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: List.generate(navbarMenuList.length, (index) {
+ return InkWell(
+ key: Key("bottom_item_$index"),
+ onTap: () {
+ navigateToPage(index);
+ },
+ child: SvgPicture.asset(
+ pageIndex == index
+ ? navbarMenuList[index].activeIcon!
+ : navbarMenuList[index].inactiveIcon!,
+ width: 27,
+ ),
+ );
+ }),
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/widgets/post_item.dart b/clone-instagram-login-Refactoring/lib/app/widgets/post_item.dart
new file mode 100644
index 0000000..7dfafcc
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/widgets/post_item.dart
@@ -0,0 +1,303 @@
+import 'package:example_widget_testing/core/theme/colors.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+// import 'package:line_icons/line_icons.dart';
+
+class PostItem extends StatelessWidget {
+ final String profileImg;
+ final String name;
+ final String postImg;
+ final String caption;
+ final bool isLoved;
+ final String likedBy;
+ final String viewCount;
+ final String dayAgo;
+ final String userPhoto;
+ final VoidCallback onPressed;
+
+ const PostItem({
+ super.key,
+ required this.profileImg,
+ required this.name,
+ required this.postImg,
+ required this.caption,
+ required this.isLoved,
+ required this.likedBy,
+ required this.viewCount,
+ required this.dayAgo,
+ required this.userPhoto,
+ required this.onPressed,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ key: const Key('post_item_padding'),
+ padding: const EdgeInsets.only(bottom: 10),
+ child: Column(
+ key: const Key('post_item_column'),
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Container(
+ key: const Key('post_item_user_info_container'),
+ padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15),
+ margin: const EdgeInsets.only(bottom: 12),
+ child: Row(
+ key: const Key('post_item_user_info_row'),
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Container(
+ key: const Key('post_item_user_profile_img_container'),
+ width: 40,
+ height: 40,
+ margin: const EdgeInsets.only(right: 15),
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ image: DecorationImage(
+ image: NetworkImage(profileImg),
+ fit: BoxFit.cover,
+ ),
+ ),
+ ),
+ Expanded(
+ key: const Key('post_item_user_name_expanded'),
+ child: Text(
+ key: const Key('post_item_user_name_text'),
+ name,
+ style: const TextStyle(
+ color: white,
+ fontSize: 15,
+ fontWeight: FontWeight.w500,
+ ),
+ ),
+ ),
+ const Icon(
+ key: Key('post_item_user_more_icon'),
+ Icons.more_horiz,
+ color: white,
+ )
+ ],
+ ),
+ ),
+ Stack(
+ children: [
+ Material(
+ child: InkWell(
+ onDoubleTap: () => onPressed(),
+ child: Container(
+ key: const Key('post_item_image_container'),
+ height: 400,
+ margin: const EdgeInsets.only(bottom: 10),
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: NetworkImage(postImg),
+ fit: BoxFit.cover,
+ ),
+ ),
+ ),
+ ),
+ ),
+ // put love icon here
+ Positioned(
+ key: const Key('post_item_love_icon_positioned'),
+ bottom: 20,
+ right: 20,
+ child: Material(
+ color: Colors.transparent,
+ child: InkWell(
+ onTap: onPressed,
+ child: SvgPicture.asset(
+ key: const Key('post_item_love_icon'),
+ isLoved
+ ? "assets/images/loved_icon.svg"
+ : "assets/images/love_icon.svg",
+ width: 27,
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ Container(
+ key: const Key('post_item_actions_container'),
+ padding: const EdgeInsets.fromLTRB(15, 3, 15, 0),
+ margin: const EdgeInsets.only(bottom: 12),
+ child: Row(
+ key: const Key('post_item_actions_row'),
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Row(
+ key: const Key('post_item_actions_left_row'),
+ children: [
+ Material(
+ color: Colors.transparent,
+ child: InkWell(
+ onTap: onPressed,
+ child: SvgPicture.asset(
+ key: const Key('post_item_actions_love_icon'),
+ isLoved
+ ? "assets/images/loved_icon.svg"
+ : "assets/images/love_icon.svg",
+ width: 27,
+ ),
+ ),
+ ),
+ const SizedBox(
+ key: Key('post_item_actions_left_row_sized_box_1'),
+ width: 20),
+ SvgPicture.asset(
+ "assets/images/comment_icon.svg",
+ key: const Key('post_item_actions_comment_icon'),
+ width: 27,
+ ),
+ const SizedBox(
+ key: Key('post_item_actions_left_row_sized_box_2'),
+ width: 20),
+ SvgPicture.asset(
+ "assets/images/message_icon.svg",
+ key: const Key('post_item_actions_message_icon'),
+ width: 27,
+ ),
+ ],
+ ),
+ SvgPicture.asset(
+ "assets/images/save_icon.svg",
+ key: const Key('post_item_actions_save_icon'),
+ width: 27,
+ ),
+ ],
+ ),
+ ),
+ Container(
+ key: const Key('post_item_likes_container'),
+ padding: const EdgeInsets.symmetric(horizontal: 15),
+ margin: const EdgeInsets.only(bottom: 12),
+ child: RichText(
+ key: const Key('post_item_likes_rich_text'),
+ text: TextSpan(
+ children: [
+ TextSpan(
+ text: "Liked by $likedBy and Other",
+ style: const TextStyle(
+ fontSize: 15,
+ fontWeight: FontWeight.w500,
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ Container(
+ key: const Key('post_item_caption_container'),
+ padding: const EdgeInsets.symmetric(horizontal: 15),
+ margin: const EdgeInsets.only(bottom: 12),
+ child: RichText(
+ key: const Key('post_item_caption_rich_text'),
+ text: TextSpan(
+ children: [
+ TextSpan(
+ text: "$name ",
+ style: const TextStyle(
+ fontSize: 15, fontWeight: FontWeight.w700),
+ ),
+ TextSpan(
+ text: caption,
+ style: const TextStyle(
+ fontSize: 15, fontWeight: FontWeight.w500),
+ ),
+ ],
+ ),
+ ),
+ ),
+ Container(
+ key: const Key('post_item_view_comments_container'),
+ padding: const EdgeInsets.symmetric(horizontal: 15),
+ margin: const EdgeInsets.only(bottom: 12),
+ child: Text(
+ key: const Key('post_item_view_comments_text'),
+ "View $viewCount comments",
+ style: TextStyle(
+ color: white.withOpacity(0.5),
+ fontSize: 15,
+ fontWeight: FontWeight.w500),
+ ),
+ ),
+ Container(
+ key: const Key('post_item_add_comment_container'),
+ padding: const EdgeInsets.symmetric(horizontal: 15),
+ margin: const EdgeInsets.only(bottom: 12),
+ child: Row(
+ key: const Key('post_item_add_comment_row'),
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Row(
+ key: const Key('post_item_add_comment_left_row'),
+ children: [
+ Container(
+ key: const Key('post_item_add_comment_avatar_container'),
+ width: 30,
+ height: 30,
+ margin: const EdgeInsets.only(right: 15),
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ image: DecorationImage(
+ image: NetworkImage(userPhoto),
+ fit: BoxFit.cover,
+ ),
+ ),
+ ),
+ Text(
+ key: const Key('post_item_add_comment_text'),
+ "Add a comment...",
+ style: TextStyle(
+ color: white.withOpacity(0.5),
+ fontSize: 15,
+ fontWeight: FontWeight.w500,
+ ),
+ ),
+ ],
+ ),
+ Row(
+ key: const Key('post_item_add_comment_right_row'),
+ children: [
+ const Text(
+ key: Key('post_item_add_laugh_emoji_text'),
+ "😂",
+ style: TextStyle(fontSize: 20),
+ ),
+ const SizedBox(width: 10),
+ const Text(
+ key: Key('post_item_add_love_emoji_text'),
+ "😍",
+ style: TextStyle(fontSize: 20),
+ ),
+ const SizedBox(width: 10),
+ Icon(
+ key: const Key('post_item_add_circle_icon'),
+ Icons.add_circle,
+ color: white.withOpacity(0.5),
+ size: 18,
+ )
+ ],
+ )
+ ],
+ ),
+ ),
+ Padding(
+ key: const Key('post_item_day_ago_padding'),
+ padding: const EdgeInsets.symmetric(horizontal: 15),
+ child: Text(
+ key: const Key('post_item_day_ago_text'),
+ dayAgo,
+ style: TextStyle(
+ color: white.withOpacity(0.5),
+ fontSize: 15,
+ fontWeight: FontWeight.w500,
+ ),
+ ),
+ )
+ ],
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/widgets/post_thumbnail.dart b/clone-instagram-login-Refactoring/lib/app/widgets/post_thumbnail.dart
new file mode 100644
index 0000000..1808aa8
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/widgets/post_thumbnail.dart
@@ -0,0 +1,23 @@
+import 'package:flutter/widgets.dart';
+
+class PostThumbnail extends StatelessWidget {
+ final String imageUrl;
+
+ const PostThumbnail({super.key, required this.imageUrl});
+
+ @override
+ Widget build(BuildContext context) {
+ final size = MediaQuery.of(context).size;
+ return Container(
+ key: Key(imageUrl),
+ width: (size.width - 3) / 3,
+ height: (size.width - 3) / 3,
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: NetworkImage(imageUrl),
+ fit: BoxFit.cover,
+ ),
+ ),
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/lib/app/widgets/root_app.dart b/clone-instagram-login-Refactoring/lib/app/widgets/root_app.dart
new file mode 100644
index 0000000..b892978
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/app/widgets/root_app.dart
@@ -0,0 +1,20 @@
+// import 'package:example_widget_testing/core/values/constant/navbarmenu_json.dart';
+// import 'package:flutter/material.dart';
+// import 'package:flutter_svg/svg.dart';
+
+// class BottomNavbar extends StatelessWidget {
+// final int pageIndex;
+// const BottomNavbar({
+// super.key,
+// required this.pageIndex,
+// });
+
+// @override
+// Widget build(BuildContext context) {
+// void navigateToPage(int index) {
+// Navigator.pushNamed(context, navbarMenuList[index].path!);
+// }
+
+// throw UnimplementedError();
+// }
+// }
diff --git a/clone-instagram-login-Refactoring/lib/core/theme/colors.dart b/clone-instagram-login-Refactoring/lib/core/theme/colors.dart
new file mode 100644
index 0000000..898ce74
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/core/theme/colors.dart
@@ -0,0 +1,10 @@
+import 'package:flutter/material.dart';
+
+const appBarColor = Color(0xFF131313);
+const appFooterColor = Color(0xFF131313);
+const primary = Color(0xFF000000);
+const white = Color(0xFFFFFFFF);
+const black = Color(0xFF000000);
+const textFieldBackground = Color(0xFF262626);
+const buttonFollowColor = Color(0xFF0494F5);
+const storyBorderColor = [Color(0xFF9B2282), Color(0xFFEEA863)];
diff --git a/clone-instagram-login-Refactoring/lib/core/values/constant/navbarmenu_json.dart b/clone-instagram-login-Refactoring/lib/core/values/constant/navbarmenu_json.dart
new file mode 100644
index 0000000..4544952
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/core/values/constant/navbarmenu_json.dart
@@ -0,0 +1,42 @@
+import '../../../app/data/models/navbar_menu.dart';
+
+List navbarmenu = [
+ {
+ "id": 1,
+ "name": "Home",
+ "active_icon": "assets/images/home_active_icon.svg",
+ "inactive_icon": "assets/images/home_icon.svg",
+ "path": "/home",
+ },
+ {
+ "id": 2,
+ "name": "Search",
+ "active_icon": "assets/images/search_active_icon.svg",
+ "inactive_icon": "assets/images/search_icon.svg",
+ "path": "/search"
+ },
+ {
+ "id": 3,
+ "name": "Upload",
+ "active_icon": "assets/images/upload_active_icon.svg",
+ "inactive_icon": "assets/images/upload_icon.svg",
+ "path": "/upload"
+ },
+ {
+ "id": 4,
+ "name": "Activity",
+ "active_icon": "assets/images/love_active_icon.svg",
+ "inactive_icon": "assets/images/love_icon.svg",
+ "path": "/activity"
+ },
+ {
+ "id": 5,
+ "name": "Account",
+ "active_icon": "assets/images/account_active_icon.svg",
+ "inactive_icon": "assets/images/account_icon.svg",
+ "path": "/account"
+ }
+];
+
+List navbarMenuList =
+ navbarmenu.map((e) => NavbarMenu.fromJson(e)).toList();
diff --git a/clone-instagram-login-Refactoring/lib/core/values/constant/post_json.dart b/clone-instagram-login-Refactoring/lib/core/values/constant/post_json.dart
new file mode 100644
index 0000000..6a10e35
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/core/values/constant/post_json.dart
@@ -0,0 +1,68 @@
+List posts = [
+ {
+ "id": 1,
+ "name": "Kal El",
+ "profileImg":
+ "https://images.unsplash.com/photo-1634861949375-3fc4bd412f2f?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80",
+ "postImg":
+ "https://images.unsplash.com/photo-1634861949375-3fc4bd412f2f?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80",
+ "caption": " Nice cape, Clark.",
+ "isLoved": true,
+ "commentCount": "10",
+ "likedBy": "whereavygoes",
+ "timeAgo": "1 day ago"
+ },
+ {
+ "id": 2,
+ "name": "Martian",
+ "profileImg":
+ "https://images.unsplash.com/photo-1614935981447-893ce3858657?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=735&q=80",
+ "postImg":
+ "https://images.unsplash.com/photo-1614935981447-893ce3858657?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=735&q=80",
+ "caption":
+ " Home is where the heart is. And my heart is in the middle of nowhere.",
+ "isLoved": true,
+ "commentCount": "10",
+ "likedBy": "sonitakhoun",
+ "timeAgo": "1 day ago"
+ },
+ {
+ "id": 3,
+ "name": "Arthur Curry",
+ "profileImg":
+ "https://images.unsplash.com/photo-1584102534935-a63e84096e83?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1469&q=80",
+ "postImg":
+ "https://images.unsplash.com/photo-1584102534935-a63e84096e83?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1469&q=80",
+ "caption": " G'day, mate.",
+ "isLoved": false,
+ "commentCount": "60",
+ "likedBy": "Amber Heard",
+ "timeAgo": "3 day ago"
+ },
+ {
+ "id": 4,
+ "name": "Victor Stone",
+ "profileImg":
+ "https://images.unsplash.com/photo-1616142914433-71120bc70202?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1528&q=80",
+ "postImg":
+ "https://images.unsplash.com/photo-1616142914433-71120bc70202?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1528&q=80",
+ "caption": "It's all encoded",
+ "isLoved": false,
+ "commentCount": "70",
+ "likedBy": "sonitakhoun",
+ "timeAgo": "3 day ago"
+ },
+ {
+ "id": 5,
+ "name": "Bruce Wayne",
+ "profileImg":
+ "https://images.unsplash.com/photo-1497124401559-3e75ec2ed794?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80",
+ "postImg":
+ "https://images.unsplash.com/photo-1497124401559-3e75ec2ed794?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80",
+ "caption": "I'm Batman",
+ "isLoved": false,
+ "commentCount": "70",
+ "likedBy": "sonitakhoun",
+ "timeAgo": "3 day ago"
+ }
+];
diff --git a/clone-instagram-login-Refactoring/lib/core/values/constant/profile_json.dart b/clone-instagram-login-Refactoring/lib/core/values/constant/profile_json.dart
new file mode 100644
index 0000000..aa1666e
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/core/values/constant/profile_json.dart
@@ -0,0 +1,14 @@
+final profileJson = {
+ "username": "iclop",
+ "name": "IClop Student",
+ "bio": "Apperentice",
+ "profilePic":
+ "https://images.unsplash.com/photo-1614935981447-893ce3858657?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=735&q=80",
+ "profileBackground": "assets/images/profile_background.jpg",
+ "profileBackgroundBlur": "assets/images/profile_background_blur.jpg",
+ "stats": [
+ {"count": 0, "label": "Posts"},
+ {"count": 0, "label": "Followers"},
+ {"count": 0, "label": "Following"}
+ ]
+};
diff --git a/clone-instagram-login-Refactoring/lib/core/values/constant/profile_tabs_json.dart b/clone-instagram-login-Refactoring/lib/core/values/constant/profile_tabs_json.dart
new file mode 100644
index 0000000..9d0680f
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/core/values/constant/profile_tabs_json.dart
@@ -0,0 +1,14 @@
+import 'package:flutter/material.dart';
+
+final List tabs = [
+ {
+ "id": 0,
+ "title": "posts",
+ "icon": Icons.grid_on_outlined,
+ },
+ {
+ "id": 1,
+ "title": "tags",
+ "icon": Icons.person_pin_outlined,
+ }
+];
diff --git a/clone-instagram-login-Refactoring/lib/core/values/constant/search_json.dart b/clone-instagram-login-Refactoring/lib/core/values/constant/search_json.dart
new file mode 100644
index 0000000..0bc5ba4
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/core/values/constant/search_json.dart
@@ -0,0 +1,28 @@
+List searchCategories = [
+ "Shop",
+ "Decor",
+ "Travel",
+ "Architechture",
+ "Food",
+ "Art",
+ "Style",
+ "TV & Movies",
+ "Music",
+ "DIY",
+ "Comics"
+];
+
+List searchImages = [
+ "https://images.unsplash.com/photo-1504123010103-b1f3fe484a32?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80",
+ "https://images.unsplash.com/photo-1497316730643-415fac54a2af?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=764&q=80",
+ "https://images.unsplash.com/photo-1576092762793-c0e9395ec4b9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80",
+ "https://images.unsplash.com/photo-1597182322624-232ca7819eaa?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=688&q=80",
+ "https://images.unsplash.com/photo-1581091007718-0c50d599bfd0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80",
+ "https://images.unsplash.com/photo-1503428593586-e225b39bddfe?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80",
+ "https://images.unsplash.com/photo-1497124401559-3e75ec2ed794?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80",
+ "https://images.unsplash.com/photo-1616142914433-71120bc70202?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1528&q=80",
+ "https://images.unsplash.com/photo-1584102534935-a63e84096e83?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1469&q=80",
+ "https://images.unsplash.com/photo-1614935981447-893ce3858657?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=735&q=80",
+ "https://images.unsplash.com/photo-1634861949375-3fc4bd412f2f?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80",
+ "https://images.unsplash.com/photo-1506901437675-cde80ff9c746?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60",
+];
diff --git a/clone-instagram-login-Refactoring/lib/core/values/constant/story_json.dart b/clone-instagram-login-Refactoring/lib/core/values/constant/story_json.dart
new file mode 100644
index 0000000..1450ae5
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/core/values/constant/story_json.dart
@@ -0,0 +1,38 @@
+// user prfile
+String profile =
+ "https://images.unsplash.com/photo-1504123010103-b1f3fe484a32?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80";
+String name = "Barry Allen";
+
+// stories
+List stories = [
+ {
+ "id": 1,
+ "img":
+ "https://images.unsplash.com/photo-1503428593586-e225b39bddfe?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80",
+ "name": "Lois Lane"
+ },
+ {
+ "id": 2,
+ "img":
+ "https://images.unsplash.com/photo-1581091007718-0c50d599bfd0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80",
+ "name": "Silas Stone"
+ },
+ {
+ "id": 3,
+ "img":
+ "https://images.unsplash.com/photo-1597182322624-232ca7819eaa?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=688&q=80",
+ "name": "Mera"
+ },
+ {
+ "id": 4,
+ "img":
+ "https://images.unsplash.com/photo-1576092762793-c0e9395ec4b9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80",
+ "name": "Pennyworth"
+ },
+ {
+ "id": 5,
+ "img":
+ "https://images.unsplash.com/photo-1497316730643-415fac54a2af?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=764&q=80",
+ "name": "Jimmy Olsen"
+ }
+];
diff --git a/clone-instagram-login-Refactoring/lib/main.dart b/clone-instagram-login-Refactoring/lib/main.dart
new file mode 100644
index 0000000..6c30e19
--- /dev/null
+++ b/clone-instagram-login-Refactoring/lib/main.dart
@@ -0,0 +1,44 @@
+import 'package:example_widget_testing/app/modules/account/account_page.dart';
+import 'package:example_widget_testing/app/modules/activity/activity_page.dart';
+import 'package:example_widget_testing/app/modules/home/home_page.dart';
+import 'package:example_widget_testing/app/modules/login/login_page.dart';
+import 'package:example_widget_testing/app/modules/post/post_page.dart';
+import 'package:example_widget_testing/app/modules/search/search_page.dart';
+import 'package:example_widget_testing/core/values/constant/post_json.dart';
+import 'package:example_widget_testing/core/values/constant/profile_json.dart';
+import 'package:example_widget_testing/core/values/constant/search_json.dart';
+import 'package:flutter/material.dart';
+
+import 'app/modules/upload/upload_page.dart';
+import 'core/values/constant/story_json.dart';
+
+void main() {
+ runApp(const MyApp());
+}
+
+class MyApp extends StatelessWidget {
+ const MyApp({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ debugShowCheckedModeBanner: false,
+ title: 'Flutter Demo',
+ theme: ThemeData(
+ primarySwatch: Colors.blue,
+ ),
+ home: const LoginPage(),
+ routes: {
+ '/login': (context) => const LoginPage(),
+ '/home': (context) =>
+ HomePage(posts: posts, stories: stories, profileData: profileJson),
+ '/search': (context) => SearchPage(searchPosts: searchImages),
+ '/upload': (context) => const UploadPage(),
+ '/activity': (context) => const ActivityPage(),
+ '/account': (context) => AccountPage(
+ profileData: profileJson, posts: posts, stories: stories),
+ '/post': (context) => PostPage(posts: posts),
+ },
+ );
+ }
+}
diff --git a/clone-instagram-login-Refactoring/linux/.gitignore b/clone-instagram-login-Refactoring/linux/.gitignore
new file mode 100644
index 0000000..d3896c9
--- /dev/null
+++ b/clone-instagram-login-Refactoring/linux/.gitignore
@@ -0,0 +1 @@
+flutter/ephemeral
diff --git a/clone-instagram-login-Refactoring/linux/CMakeLists.txt b/clone-instagram-login-Refactoring/linux/CMakeLists.txt
new file mode 100644
index 0000000..a81fd7a
--- /dev/null
+++ b/clone-instagram-login-Refactoring/linux/CMakeLists.txt
@@ -0,0 +1,138 @@
+# Project-level configuration.
+cmake_minimum_required(VERSION 3.10)
+project(runner LANGUAGES CXX)
+
+# The name of the executable created for the application. Change this to change
+# the on-disk name of your application.
+set(BINARY_NAME "example_widget_testing")
+# The unique GTK application identifier for this application. See:
+# https://wiki.gnome.org/HowDoI/ChooseApplicationID
+set(APPLICATION_ID "com.example.example_widget_testing")
+
+# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
+# versions of CMake.
+cmake_policy(SET CMP0063 NEW)
+
+# Load bundled libraries from the lib/ directory relative to the binary.
+set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
+
+# Root filesystem for cross-building.
+if(FLUTTER_TARGET_PLATFORM_SYSROOT)
+ set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
+ set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
+ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+endif()
+
+# Define build configuration options.
+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+ set(CMAKE_BUILD_TYPE "Debug" CACHE
+ STRING "Flutter build mode" FORCE)
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
+ "Debug" "Profile" "Release")
+endif()
+
+# Compilation settings that should be applied to most targets.
+#
+# Be cautious about adding new options here, as plugins use this function by
+# default. In most cases, you should add new options to specific targets instead
+# of modifying this function.
+function(APPLY_STANDARD_SETTINGS TARGET)
+ target_compile_features(${TARGET} PUBLIC cxx_std_14)
+ target_compile_options(${TARGET} PRIVATE -Wall -Werror)
+ target_compile_options(${TARGET} PRIVATE "$<$>:-O3>")
+ target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>")
+endfunction()
+
+# Flutter library and tool build rules.
+set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
+add_subdirectory(${FLUTTER_MANAGED_DIR})
+
+# System-level dependencies.
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
+
+add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
+
+# Define the application target. To change its name, change BINARY_NAME above,
+# not the value here, or `flutter run` will no longer work.
+#
+# Any new source files that you add to the application should be added here.
+add_executable(${BINARY_NAME}
+ "main.cc"
+ "my_application.cc"
+ "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
+)
+
+# Apply the standard set of build settings. This can be removed for applications
+# that need different build settings.
+apply_standard_settings(${BINARY_NAME})
+
+# Add dependency libraries. Add any application-specific dependencies here.
+target_link_libraries(${BINARY_NAME} PRIVATE flutter)
+target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
+
+# Run the Flutter tool portions of the build. This must not be removed.
+add_dependencies(${BINARY_NAME} flutter_assemble)
+
+# Only the install-generated bundle's copy of the executable will launch
+# correctly, since the resources must in the right relative locations. To avoid
+# people trying to run the unbundled copy, put it in a subdirectory instead of
+# the default top-level location.
+set_target_properties(${BINARY_NAME}
+ PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
+)
+
+# Generated plugin build rules, which manage building the plugins and adding
+# them to the application.
+include(flutter/generated_plugins.cmake)
+
+
+# === Installation ===
+# By default, "installing" just makes a relocatable bundle in the build
+# directory.
+set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
+if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+ set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
+endif()
+
+# Start with a clean build bundle directory every time.
+install(CODE "
+ file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
+ " COMPONENT Runtime)
+
+set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
+set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
+
+install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
+ COMPONENT Runtime)
+
+install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
+ COMPONENT Runtime)
+
+install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+ COMPONENT Runtime)
+
+foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
+ install(FILES "${bundled_library}"
+ DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+ COMPONENT Runtime)
+endforeach(bundled_library)
+
+# Fully re-copy the assets directory on each build to avoid having stale files
+# from a previous install.
+set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
+install(CODE "
+ file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
+ " COMPONENT Runtime)
+install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
+ DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
+
+# Install the AOT library on non-Debug builds only.
+if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
+ install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+ COMPONENT Runtime)
+endif()
diff --git a/clone-instagram-login-Refactoring/linux/flutter/CMakeLists.txt b/clone-instagram-login-Refactoring/linux/flutter/CMakeLists.txt
new file mode 100644
index 0000000..d5bd016
--- /dev/null
+++ b/clone-instagram-login-Refactoring/linux/flutter/CMakeLists.txt
@@ -0,0 +1,88 @@
+# This file controls Flutter-level build steps. It should not be edited.
+cmake_minimum_required(VERSION 3.10)
+
+set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
+
+# Configuration provided via flutter tool.
+include(${EPHEMERAL_DIR}/generated_config.cmake)
+
+# TODO: Move the rest of this into files in ephemeral. See
+# https://github.com/flutter/flutter/issues/57146.
+
+# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
+# which isn't available in 3.10.
+function(list_prepend LIST_NAME PREFIX)
+ set(NEW_LIST "")
+ foreach(element ${${LIST_NAME}})
+ list(APPEND NEW_LIST "${PREFIX}${element}")
+ endforeach(element)
+ set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
+endfunction()
+
+# === Flutter Library ===
+# System-level dependencies.
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
+pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
+pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
+
+set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
+
+# Published to parent scope for install step.
+set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
+set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
+set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
+set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
+
+list(APPEND FLUTTER_LIBRARY_HEADERS
+ "fl_basic_message_channel.h"
+ "fl_binary_codec.h"
+ "fl_binary_messenger.h"
+ "fl_dart_project.h"
+ "fl_engine.h"
+ "fl_json_message_codec.h"
+ "fl_json_method_codec.h"
+ "fl_message_codec.h"
+ "fl_method_call.h"
+ "fl_method_channel.h"
+ "fl_method_codec.h"
+ "fl_method_response.h"
+ "fl_plugin_registrar.h"
+ "fl_plugin_registry.h"
+ "fl_standard_message_codec.h"
+ "fl_standard_method_codec.h"
+ "fl_string_codec.h"
+ "fl_value.h"
+ "fl_view.h"
+ "flutter_linux.h"
+)
+list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
+add_library(flutter INTERFACE)
+target_include_directories(flutter INTERFACE
+ "${EPHEMERAL_DIR}"
+)
+target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
+target_link_libraries(flutter INTERFACE
+ PkgConfig::GTK
+ PkgConfig::GLIB
+ PkgConfig::GIO
+)
+add_dependencies(flutter flutter_assemble)
+
+# === Flutter tool backend ===
+# _phony_ is a non-existent file to force this command to run every time,
+# since currently there's no way to get a full input/output list from the
+# flutter tool.
+add_custom_command(
+ OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
+ ${CMAKE_CURRENT_BINARY_DIR}/_phony_
+ COMMAND ${CMAKE_COMMAND} -E env
+ ${FLUTTER_TOOL_ENVIRONMENT}
+ "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
+ ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
+ VERBATIM
+)
+add_custom_target(flutter_assemble DEPENDS
+ "${FLUTTER_LIBRARY}"
+ ${FLUTTER_LIBRARY_HEADERS}
+)
diff --git a/clone-instagram-login-Refactoring/linux/flutter/generated_plugin_registrant.cc b/clone-instagram-login-Refactoring/linux/flutter/generated_plugin_registrant.cc
new file mode 100644
index 0000000..e71a16d
--- /dev/null
+++ b/clone-instagram-login-Refactoring/linux/flutter/generated_plugin_registrant.cc
@@ -0,0 +1,11 @@
+//
+// Generated file. Do not edit.
+//
+
+// clang-format off
+
+#include "generated_plugin_registrant.h"
+
+
+void fl_register_plugins(FlPluginRegistry* registry) {
+}
diff --git a/clone-instagram-login-Refactoring/linux/flutter/generated_plugin_registrant.h b/clone-instagram-login-Refactoring/linux/flutter/generated_plugin_registrant.h
new file mode 100644
index 0000000..e0f0a47
--- /dev/null
+++ b/clone-instagram-login-Refactoring/linux/flutter/generated_plugin_registrant.h
@@ -0,0 +1,15 @@
+//
+// Generated file. Do not edit.
+//
+
+// clang-format off
+
+#ifndef GENERATED_PLUGIN_REGISTRANT_
+#define GENERATED_PLUGIN_REGISTRANT_
+
+#include
+
+// Registers Flutter plugins.
+void fl_register_plugins(FlPluginRegistry* registry);
+
+#endif // GENERATED_PLUGIN_REGISTRANT_
diff --git a/clone-instagram-login-Refactoring/linux/flutter/generated_plugins.cmake b/clone-instagram-login-Refactoring/linux/flutter/generated_plugins.cmake
new file mode 100644
index 0000000..2e1de87
--- /dev/null
+++ b/clone-instagram-login-Refactoring/linux/flutter/generated_plugins.cmake
@@ -0,0 +1,23 @@
+#
+# Generated file, do not edit.
+#
+
+list(APPEND FLUTTER_PLUGIN_LIST
+)
+
+list(APPEND FLUTTER_FFI_PLUGIN_LIST
+)
+
+set(PLUGIN_BUNDLED_LIBRARIES)
+
+foreach(plugin ${FLUTTER_PLUGIN_LIST})
+ add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
+ target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
+ list(APPEND PLUGIN_BUNDLED_LIBRARIES $)
+ list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
+endforeach(plugin)
+
+foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
+ add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
+ list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
+endforeach(ffi_plugin)
diff --git a/clone-instagram-login-Refactoring/linux/main.cc b/clone-instagram-login-Refactoring/linux/main.cc
new file mode 100644
index 0000000..e7c5c54
--- /dev/null
+++ b/clone-instagram-login-Refactoring/linux/main.cc
@@ -0,0 +1,6 @@
+#include "my_application.h"
+
+int main(int argc, char** argv) {
+ g_autoptr(MyApplication) app = my_application_new();
+ return g_application_run(G_APPLICATION(app), argc, argv);
+}
diff --git a/clone-instagram-login-Refactoring/linux/my_application.cc b/clone-instagram-login-Refactoring/linux/my_application.cc
new file mode 100644
index 0000000..d312ba8
--- /dev/null
+++ b/clone-instagram-login-Refactoring/linux/my_application.cc
@@ -0,0 +1,104 @@
+#include "my_application.h"
+
+#include
+#ifdef GDK_WINDOWING_X11
+#include
+#endif
+
+#include "flutter/generated_plugin_registrant.h"
+
+struct _MyApplication {
+ GtkApplication parent_instance;
+ char** dart_entrypoint_arguments;
+};
+
+G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
+
+// Implements GApplication::activate.
+static void my_application_activate(GApplication* application) {
+ MyApplication* self = MY_APPLICATION(application);
+ GtkWindow* window =
+ GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
+
+ // Use a header bar when running in GNOME as this is the common style used
+ // by applications and is the setup most users will be using (e.g. Ubuntu
+ // desktop).
+ // If running on X and not using GNOME then just use a traditional title bar
+ // in case the window manager does more exotic layout, e.g. tiling.
+ // If running on Wayland assume the header bar will work (may need changing
+ // if future cases occur).
+ gboolean use_header_bar = TRUE;
+#ifdef GDK_WINDOWING_X11
+ GdkScreen* screen = gtk_window_get_screen(window);
+ if (GDK_IS_X11_SCREEN(screen)) {
+ const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
+ if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
+ use_header_bar = FALSE;
+ }
+ }
+#endif
+ if (use_header_bar) {
+ GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
+ gtk_widget_show(GTK_WIDGET(header_bar));
+ gtk_header_bar_set_title(header_bar, "example_widget_testing");
+ gtk_header_bar_set_show_close_button(header_bar, TRUE);
+ gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
+ } else {
+ gtk_window_set_title(window, "example_widget_testing");
+ }
+
+ gtk_window_set_default_size(window, 1280, 720);
+ gtk_widget_show(GTK_WIDGET(window));
+
+ g_autoptr(FlDartProject) project = fl_dart_project_new();
+ fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
+
+ FlView* view = fl_view_new(project);
+ gtk_widget_show(GTK_WIDGET(view));
+ gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
+
+ fl_register_plugins(FL_PLUGIN_REGISTRY(view));
+
+ gtk_widget_grab_focus(GTK_WIDGET(view));
+}
+
+// Implements GApplication::local_command_line.
+static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) {
+ MyApplication* self = MY_APPLICATION(application);
+ // Strip out the first argument as it is the binary name.
+ self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
+
+ g_autoptr(GError) error = nullptr;
+ if (!g_application_register(application, nullptr, &error)) {
+ g_warning("Failed to register: %s", error->message);
+ *exit_status = 1;
+ return TRUE;
+ }
+
+ g_application_activate(application);
+ *exit_status = 0;
+
+ return TRUE;
+}
+
+// Implements GObject::dispose.
+static void my_application_dispose(GObject* object) {
+ MyApplication* self = MY_APPLICATION(object);
+ g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
+ G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
+}
+
+static void my_application_class_init(MyApplicationClass* klass) {
+ G_APPLICATION_CLASS(klass)->activate = my_application_activate;
+ G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
+ G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
+}
+
+static void my_application_init(MyApplication* self) {}
+
+MyApplication* my_application_new() {
+ return MY_APPLICATION(g_object_new(my_application_get_type(),
+ "application-id", APPLICATION_ID,
+ "flags", G_APPLICATION_NON_UNIQUE,
+ nullptr));
+}
diff --git a/clone-instagram-login-Refactoring/linux/my_application.h b/clone-instagram-login-Refactoring/linux/my_application.h
new file mode 100644
index 0000000..72271d5
--- /dev/null
+++ b/clone-instagram-login-Refactoring/linux/my_application.h
@@ -0,0 +1,18 @@
+#ifndef FLUTTER_MY_APPLICATION_H_
+#define FLUTTER_MY_APPLICATION_H_
+
+#include
+
+G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
+ GtkApplication)
+
+/**
+ * my_application_new:
+ *
+ * Creates a new Flutter-based application.
+ *
+ * Returns: a new #MyApplication.
+ */
+MyApplication* my_application_new();
+
+#endif // FLUTTER_MY_APPLICATION_H_
diff --git a/clone-instagram-login-Refactoring/macos/.gitignore b/clone-instagram-login-Refactoring/macos/.gitignore
new file mode 100644
index 0000000..746adbb
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/.gitignore
@@ -0,0 +1,7 @@
+# Flutter-related
+**/Flutter/ephemeral/
+**/Pods/
+
+# Xcode-related
+**/dgph
+**/xcuserdata/
diff --git a/clone-instagram-login-Refactoring/macos/Flutter/Flutter-Debug.xcconfig b/clone-instagram-login-Refactoring/macos/Flutter/Flutter-Debug.xcconfig
new file mode 100644
index 0000000..c2efd0b
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Flutter/Flutter-Debug.xcconfig
@@ -0,0 +1 @@
+#include "ephemeral/Flutter-Generated.xcconfig"
diff --git a/clone-instagram-login-Refactoring/macos/Flutter/Flutter-Release.xcconfig b/clone-instagram-login-Refactoring/macos/Flutter/Flutter-Release.xcconfig
new file mode 100644
index 0000000..c2efd0b
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Flutter/Flutter-Release.xcconfig
@@ -0,0 +1 @@
+#include "ephemeral/Flutter-Generated.xcconfig"
diff --git a/clone-instagram-login-Refactoring/macos/Flutter/GeneratedPluginRegistrant.swift b/clone-instagram-login-Refactoring/macos/Flutter/GeneratedPluginRegistrant.swift
new file mode 100644
index 0000000..cccf817
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -0,0 +1,10 @@
+//
+// Generated file. Do not edit.
+//
+
+import FlutterMacOS
+import Foundation
+
+
+func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
+}
diff --git a/clone-instagram-login-Refactoring/macos/Runner.xcodeproj/project.pbxproj b/clone-instagram-login-Refactoring/macos/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..a35d500
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,572 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 51;
+ objects = {
+
+/* Begin PBXAggregateTarget section */
+ 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */;
+ buildPhases = (
+ 33CC111E2044C6BF0003C045 /* ShellScript */,
+ );
+ dependencies = (
+ );
+ name = "Flutter Assemble";
+ productName = FLX;
+ };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+ 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
+ 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
+ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
+ 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
+ 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 33CC111A2044C6BA0003C045;
+ remoteInfo = FLX;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 33CC110E2044A8840003C045 /* Bundle Framework */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ );
+ name = "Bundle Framework";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; };
+ 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; };
+ 33CC10ED2044A3C60003C045 /* example_widget_testing.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "example_widget_testing.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; };
+ 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; };
+ 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; };
+ 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; };
+ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; };
+ 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; };
+ 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; };
+ 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; };
+ 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; };
+ 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; };
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; };
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 33CC10EA2044A3C60003C045 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 33BA886A226E78AF003329D5 /* Configs */ = {
+ isa = PBXGroup;
+ children = (
+ 33E5194F232828860026EE4D /* AppInfo.xcconfig */,
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */,
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+ 333000ED22D3DE5D00554162 /* Warnings.xcconfig */,
+ );
+ path = Configs;
+ sourceTree = "";
+ };
+ 33CC10E42044A3C60003C045 = {
+ isa = PBXGroup;
+ children = (
+ 33FAB671232836740065AC1E /* Runner */,
+ 33CEB47122A05771004F2AC0 /* Flutter */,
+ 33CC10EE2044A3C60003C045 /* Products */,
+ D73912EC22F37F3D000D13A0 /* Frameworks */,
+ );
+ sourceTree = "";
+ };
+ 33CC10EE2044A3C60003C045 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 33CC10ED2044A3C60003C045 /* example_widget_testing.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 33CC11242044D66E0003C045 /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 33CC10F22044A3C60003C045 /* Assets.xcassets */,
+ 33CC10F42044A3C60003C045 /* MainMenu.xib */,
+ 33CC10F72044A3C60003C045 /* Info.plist */,
+ );
+ name = Resources;
+ path = ..;
+ sourceTree = "";
+ };
+ 33CEB47122A05771004F2AC0 /* Flutter */ = {
+ isa = PBXGroup;
+ children = (
+ 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */,
+ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
+ 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,
+ 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,
+ );
+ path = Flutter;
+ sourceTree = "";
+ };
+ 33FAB671232836740065AC1E /* Runner */ = {
+ isa = PBXGroup;
+ children = (
+ 33CC10F02044A3C60003C045 /* AppDelegate.swift */,
+ 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */,
+ 33E51913231747F40026EE4D /* DebugProfile.entitlements */,
+ 33E51914231749380026EE4D /* Release.entitlements */,
+ 33CC11242044D66E0003C045 /* Resources */,
+ 33BA886A226E78AF003329D5 /* Configs */,
+ );
+ path = Runner;
+ sourceTree = "";
+ };
+ D73912EC22F37F3D000D13A0 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 33CC10EC2044A3C60003C045 /* Runner */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
+ buildPhases = (
+ 33CC10E92044A3C60003C045 /* Sources */,
+ 33CC10EA2044A3C60003C045 /* Frameworks */,
+ 33CC10EB2044A3C60003C045 /* Resources */,
+ 33CC110E2044A8840003C045 /* Bundle Framework */,
+ 3399D490228B24CF009A79C7 /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 33CC11202044C79F0003C045 /* PBXTargetDependency */,
+ );
+ name = Runner;
+ productName = Runner;
+ productReference = 33CC10ED2044A3C60003C045 /* example_widget_testing.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 33CC10E52044A3C60003C045 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 0920;
+ LastUpgradeCheck = 1300;
+ ORGANIZATIONNAME = "";
+ TargetAttributes = {
+ 33CC10EC2044A3C60003C045 = {
+ CreatedOnToolsVersion = 9.2;
+ LastSwiftMigration = 1100;
+ ProvisioningStyle = Automatic;
+ SystemCapabilities = {
+ com.apple.Sandbox = {
+ enabled = 1;
+ };
+ };
+ };
+ 33CC111A2044C6BA0003C045 = {
+ CreatedOnToolsVersion = 9.2;
+ ProvisioningStyle = Manual;
+ };
+ };
+ };
+ buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 33CC10E42044A3C60003C045;
+ productRefGroup = 33CC10EE2044A3C60003C045 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 33CC10EC2044A3C60003C045 /* Runner */,
+ 33CC111A2044C6BA0003C045 /* Flutter Assemble */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 33CC10EB2044A3C60003C045 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
+ 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 3399D490228B24CF009A79C7 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ );
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n";
+ };
+ 33CC111E2044C6BF0003C045 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ Flutter/ephemeral/FlutterInputs.xcfilelist,
+ );
+ inputPaths = (
+ Flutter/ephemeral/tripwire,
+ );
+ outputFileListPaths = (
+ Flutter/ephemeral/FlutterOutputs.xcfilelist,
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 33CC10E92044A3C60003C045 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */,
+ 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */,
+ 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 33CC11202044C79F0003C045 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */;
+ targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 33CC10F42044A3C60003C045 /* MainMenu.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 33CC10F52044A3C60003C045 /* Base */,
+ );
+ name = MainMenu.xib;
+ path = Runner;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 338D0CE9231458BD00FA5F75 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CODE_SIGN_IDENTITY = "-";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = macosx;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ };
+ name = Profile;
+ };
+ 338D0CEA231458BD00FA5F75 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Profile;
+ };
+ 338D0CEB231458BD00FA5F75 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Manual;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Profile;
+ };
+ 33CC10F92044A3C60003C045 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CODE_SIGN_IDENTITY = "-";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = macosx;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ 33CC10FA2044A3C60003C045 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CODE_SIGN_IDENTITY = "-";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = macosx;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ };
+ name = Release;
+ };
+ 33CC10FC2044A3C60003C045 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ 33CC10FD2044A3C60003C045 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Release;
+ };
+ 33CC111C2044C6BA0003C045 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Manual;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 33CC111D2044C6BA0003C045 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 33CC10F92044A3C60003C045 /* Debug */,
+ 33CC10FA2044A3C60003C045 /* Release */,
+ 338D0CE9231458BD00FA5F75 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 33CC10FC2044A3C60003C045 /* Debug */,
+ 33CC10FD2044A3C60003C045 /* Release */,
+ 338D0CEA231458BD00FA5F75 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 33CC111C2044C6BA0003C045 /* Debug */,
+ 33CC111D2044C6BA0003C045 /* Release */,
+ 338D0CEB231458BD00FA5F75 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 33CC10E52044A3C60003C045 /* Project object */;
+}
diff --git a/clone-instagram-login-Refactoring/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/clone-instagram-login-Refactoring/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/clone-instagram-login-Refactoring/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/clone-instagram-login-Refactoring/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
new file mode 100644
index 0000000..d6d7e7a
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/clone-instagram-login-Refactoring/macos/Runner.xcworkspace/contents.xcworkspacedata b/clone-instagram-login-Refactoring/macos/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..1d526a1
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/clone-instagram-login-Refactoring/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/clone-instagram-login-Refactoring/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/clone-instagram-login-Refactoring/macos/Runner/AppDelegate.swift b/clone-instagram-login-Refactoring/macos/Runner/AppDelegate.swift
new file mode 100644
index 0000000..d53ef64
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Runner/AppDelegate.swift
@@ -0,0 +1,9 @@
+import Cocoa
+import FlutterMacOS
+
+@NSApplicationMain
+class AppDelegate: FlutterAppDelegate {
+ override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
+ return true
+ }
+}
diff --git a/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..a2ec33f
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,68 @@
+{
+ "images" : [
+ {
+ "size" : "16x16",
+ "idiom" : "mac",
+ "filename" : "app_icon_16.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "16x16",
+ "idiom" : "mac",
+ "filename" : "app_icon_32.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "32x32",
+ "idiom" : "mac",
+ "filename" : "app_icon_32.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "32x32",
+ "idiom" : "mac",
+ "filename" : "app_icon_64.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "128x128",
+ "idiom" : "mac",
+ "filename" : "app_icon_128.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "128x128",
+ "idiom" : "mac",
+ "filename" : "app_icon_256.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "256x256",
+ "idiom" : "mac",
+ "filename" : "app_icon_256.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "256x256",
+ "idiom" : "mac",
+ "filename" : "app_icon_512.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "512x512",
+ "idiom" : "mac",
+ "filename" : "app_icon_512.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "512x512",
+ "idiom" : "mac",
+ "filename" : "app_icon_1024.png",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
new file mode 100644
index 0000000..82b6f9d
Binary files /dev/null and b/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ
diff --git a/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
new file mode 100644
index 0000000..13b35eb
Binary files /dev/null and b/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ
diff --git a/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
new file mode 100644
index 0000000..0a3f5fa
Binary files /dev/null and b/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ
diff --git a/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
new file mode 100644
index 0000000..bdb5722
Binary files /dev/null and b/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ
diff --git a/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
new file mode 100644
index 0000000..f083318
Binary files /dev/null and b/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ
diff --git a/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
new file mode 100644
index 0000000..326c0e7
Binary files /dev/null and b/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ
diff --git a/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
new file mode 100644
index 0000000..2f1632c
Binary files /dev/null and b/clone-instagram-login-Refactoring/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ
diff --git a/clone-instagram-login-Refactoring/macos/Runner/Base.lproj/MainMenu.xib b/clone-instagram-login-Refactoring/macos/Runner/Base.lproj/MainMenu.xib
new file mode 100644
index 0000000..80e867a
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Runner/Base.lproj/MainMenu.xib
@@ -0,0 +1,343 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/clone-instagram-login-Refactoring/macos/Runner/Configs/AppInfo.xcconfig b/clone-instagram-login-Refactoring/macos/Runner/Configs/AppInfo.xcconfig
new file mode 100644
index 0000000..3fb7d2f
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Runner/Configs/AppInfo.xcconfig
@@ -0,0 +1,14 @@
+// Application-level settings for the Runner target.
+//
+// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
+// future. If not, the values below would default to using the project name when this becomes a
+// 'flutter create' template.
+
+// The application's name. By default this is also the title of the Flutter window.
+PRODUCT_NAME = example_widget_testing
+
+// The application's bundle identifier
+PRODUCT_BUNDLE_IDENTIFIER = com.example.exampleWidgetTesting
+
+// The copyright displayed in application information
+PRODUCT_COPYRIGHT = Copyright © 2023 com.example. All rights reserved.
diff --git a/clone-instagram-login-Refactoring/macos/Runner/Configs/Debug.xcconfig b/clone-instagram-login-Refactoring/macos/Runner/Configs/Debug.xcconfig
new file mode 100644
index 0000000..36b0fd9
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Runner/Configs/Debug.xcconfig
@@ -0,0 +1,2 @@
+#include "../../Flutter/Flutter-Debug.xcconfig"
+#include "Warnings.xcconfig"
diff --git a/clone-instagram-login-Refactoring/macos/Runner/Configs/Release.xcconfig b/clone-instagram-login-Refactoring/macos/Runner/Configs/Release.xcconfig
new file mode 100644
index 0000000..dff4f49
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Runner/Configs/Release.xcconfig
@@ -0,0 +1,2 @@
+#include "../../Flutter/Flutter-Release.xcconfig"
+#include "Warnings.xcconfig"
diff --git a/clone-instagram-login-Refactoring/macos/Runner/Configs/Warnings.xcconfig b/clone-instagram-login-Refactoring/macos/Runner/Configs/Warnings.xcconfig
new file mode 100644
index 0000000..42bcbf4
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Runner/Configs/Warnings.xcconfig
@@ -0,0 +1,13 @@
+WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings
+GCC_WARN_UNDECLARED_SELECTOR = YES
+CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES
+CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
+CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
+CLANG_WARN_PRAGMA_PACK = YES
+CLANG_WARN_STRICT_PROTOTYPES = YES
+CLANG_WARN_COMMA = YES
+GCC_WARN_STRICT_SELECTOR_MATCH = YES
+CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES
+CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
+GCC_WARN_SHADOW = YES
+CLANG_WARN_UNREACHABLE_CODE = YES
diff --git a/clone-instagram-login-Refactoring/macos/Runner/DebugProfile.entitlements b/clone-instagram-login-Refactoring/macos/Runner/DebugProfile.entitlements
new file mode 100644
index 0000000..dddb8a3
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Runner/DebugProfile.entitlements
@@ -0,0 +1,12 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.cs.allow-jit
+
+ com.apple.security.network.server
+
+
+
diff --git a/clone-instagram-login-Refactoring/macos/Runner/Info.plist b/clone-instagram-login-Refactoring/macos/Runner/Info.plist
new file mode 100644
index 0000000..4789daa
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Runner/Info.plist
@@ -0,0 +1,32 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIconFile
+
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ $(FLUTTER_BUILD_NAME)
+ CFBundleVersion
+ $(FLUTTER_BUILD_NUMBER)
+ LSMinimumSystemVersion
+ $(MACOSX_DEPLOYMENT_TARGET)
+ NSHumanReadableCopyright
+ $(PRODUCT_COPYRIGHT)
+ NSMainNibFile
+ MainMenu
+ NSPrincipalClass
+ NSApplication
+
+
diff --git a/clone-instagram-login-Refactoring/macos/Runner/MainFlutterWindow.swift b/clone-instagram-login-Refactoring/macos/Runner/MainFlutterWindow.swift
new file mode 100644
index 0000000..2722837
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Runner/MainFlutterWindow.swift
@@ -0,0 +1,15 @@
+import Cocoa
+import FlutterMacOS
+
+class MainFlutterWindow: NSWindow {
+ override func awakeFromNib() {
+ let flutterViewController = FlutterViewController.init()
+ let windowFrame = self.frame
+ self.contentViewController = flutterViewController
+ self.setFrame(windowFrame, display: true)
+
+ RegisterGeneratedPlugins(registry: flutterViewController)
+
+ super.awakeFromNib()
+ }
+}
diff --git a/clone-instagram-login-Refactoring/macos/Runner/Release.entitlements b/clone-instagram-login-Refactoring/macos/Runner/Release.entitlements
new file mode 100644
index 0000000..852fa1a
--- /dev/null
+++ b/clone-instagram-login-Refactoring/macos/Runner/Release.entitlements
@@ -0,0 +1,8 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+
+
diff --git a/clone-instagram-login-Refactoring/pubspec.lock b/clone-instagram-login-Refactoring/pubspec.lock
new file mode 100644
index 0000000..e34e65e
--- /dev/null
+++ b/clone-instagram-login-Refactoring/pubspec.lock
@@ -0,0 +1,476 @@
+# Generated by pub
+# See https://dart.dev/tools/pub/glossary#lockfile
+packages:
+ _fe_analyzer_shared:
+ dependency: transitive
+ description:
+ name: _fe_analyzer_shared
+ sha256: "3444216bfd127af50bbe4862d8843ed44db946dd933554f0d7285e89f10e28ac"
+ url: "https://pub.dev"
+ source: hosted
+ version: "50.0.0"
+ analyzer:
+ dependency: transitive
+ description:
+ name: analyzer
+ sha256: "68796c31f510c8455a06fed75fc97d8e5ad04d324a830322ab3efc9feb6201c1"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.2.0"
+ archive:
+ dependency: transitive
+ description:
+ name: archive
+ sha256: "80e5141fafcb3361653ce308776cfd7d45e6e9fbb429e14eec571382c0c5fecb"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.3.2"
+ args:
+ dependency: transitive
+ description:
+ name: args
+ sha256: "4cab82a83ffef80b262ddedf47a0a8e56ee6fbf7fe21e6e768b02792034dd440"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.0"
+ async:
+ dependency: transitive
+ description:
+ name: async
+ sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.10.0"
+ boolean_selector:
+ dependency: transitive
+ description:
+ name: boolean_selector
+ sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.1"
+ build:
+ dependency: transitive
+ description:
+ name: build
+ sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.1"
+ built_collection:
+ dependency: transitive
+ description:
+ name: built_collection
+ sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.1.1"
+ built_value:
+ dependency: transitive
+ description:
+ name: built_value
+ sha256: "31b7c748fd4b9adf8d25d72a4c4a59ef119f12876cf414f94f8af5131d5fa2b0"
+ url: "https://pub.dev"
+ source: hosted
+ version: "8.4.4"
+ characters:
+ dependency: transitive
+ description:
+ name: characters
+ sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.1"
+ clock:
+ dependency: transitive
+ description:
+ name: clock
+ sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.1"
+ code_builder:
+ dependency: transitive
+ description:
+ name: code_builder
+ sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.4.0"
+ collection:
+ dependency: transitive
+ description:
+ name: collection
+ sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.17.0"
+ convert:
+ dependency: transitive
+ description:
+ name: convert
+ sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.1"
+ crypto:
+ dependency: transitive
+ description:
+ name: crypto
+ sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.2"
+ cupertino_icons:
+ dependency: "direct main"
+ description:
+ name: cupertino_icons
+ sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.5"
+ dart_style:
+ dependency: transitive
+ description:
+ name: dart_style
+ sha256: "5be16bf1707658e4c03078d4a9b90208ded217fb02c163e207d334082412f2fb"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.5"
+ fake_async:
+ dependency: transitive
+ description:
+ name: fake_async
+ sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.3.1"
+ file:
+ dependency: transitive
+ description:
+ name: file
+ sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.1.4"
+ fixnum:
+ dependency: transitive
+ description:
+ name: fixnum
+ sha256: "04be3e934c52e082558cc9ee21f42f5c1cd7a1262f4c63cd0357c08d5bba81ec"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.1"
+ flutter:
+ dependency: "direct main"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ flutter_driver:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ flutter_lints:
+ dependency: "direct dev"
+ description:
+ name: flutter_lints
+ sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
+ flutter_svg:
+ dependency: "direct main"
+ description:
+ name: flutter_svg
+ sha256: "6ff9fa12892ae074092de2fa6a9938fb21dbabfdaa2ff57dc697ff912fc8d4b2"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.6"
+ flutter_test:
+ dependency: "direct dev"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ fuchsia_remote_debug_protocol:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ glob:
+ dependency: transitive
+ description:
+ name: glob
+ sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.1"
+ integration_test:
+ dependency: "direct dev"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ js:
+ dependency: transitive
+ description:
+ name: js
+ sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.6.5"
+ lints:
+ dependency: transitive
+ description:
+ name: lints
+ sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
+ logging:
+ dependency: transitive
+ description:
+ name: logging
+ sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.1"
+ matcher:
+ dependency: transitive
+ description:
+ name: matcher
+ sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.12.13"
+ material_color_utilities:
+ dependency: transitive
+ description:
+ name: material_color_utilities
+ sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.2.0"
+ meta:
+ dependency: transitive
+ description:
+ name: meta
+ sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.8.0"
+ mockito:
+ dependency: transitive
+ description:
+ name: mockito
+ sha256: "2a8a17b82b1bde04d514e75d90d634a0ac23f6cb4991f6098009dd56836aeafe"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.3.2"
+ network_image_mock:
+ dependency: "direct dev"
+ description:
+ name: network_image_mock
+ sha256: "855cdd01d42440e0cffee0d6c2370909fc31b3bcba308a59829f24f64be42db7"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.1"
+ package_config:
+ dependency: transitive
+ description:
+ name: package_config
+ sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.0"
+ path:
+ dependency: transitive
+ description:
+ name: path
+ sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.8.2"
+ path_drawing:
+ dependency: transitive
+ description:
+ name: path_drawing
+ sha256: bbb1934c0cbb03091af082a6389ca2080345291ef07a5fa6d6e078ba8682f977
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.1"
+ path_parsing:
+ dependency: transitive
+ description:
+ name: path_parsing
+ sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.1"
+ petitparser:
+ dependency: transitive
+ description:
+ name: petitparser
+ sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.1.0"
+ platform:
+ dependency: transitive
+ description:
+ name: platform
+ sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.0"
+ process:
+ dependency: transitive
+ description:
+ name: process
+ sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.2.4"
+ pub_semver:
+ dependency: transitive
+ description:
+ name: pub_semver
+ sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.3"
+ sky_engine:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.99"
+ source_gen:
+ dependency: transitive
+ description:
+ name: source_gen
+ sha256: c2bea18c95cfa0276a366270afaa2850b09b4a76db95d546f3d003dcc7011298
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.7"
+ source_span:
+ dependency: transitive
+ description:
+ name: source_span
+ sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.9.1"
+ stack_trace:
+ dependency: transitive
+ description:
+ name: stack_trace
+ sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.11.0"
+ stream_channel:
+ dependency: transitive
+ description:
+ name: stream_channel
+ sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.1"
+ string_scanner:
+ dependency: transitive
+ description:
+ name: string_scanner
+ sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.0"
+ sync_http:
+ dependency: transitive
+ description:
+ name: sync_http
+ sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.3.1"
+ term_glyph:
+ dependency: transitive
+ description:
+ name: term_glyph
+ sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.1"
+ test_api:
+ dependency: transitive
+ description:
+ name: test_api
+ sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.4.16"
+ test_cov_console:
+ dependency: "direct dev"
+ description:
+ name: test_cov_console
+ sha256: "73519e8be3689d73f5cffb652c12c310acacf48379396d834da937094836e65e"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.2.2"
+ typed_data:
+ dependency: transitive
+ description:
+ name: typed_data
+ sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.3.1"
+ vector_math:
+ dependency: transitive
+ description:
+ name: vector_math
+ sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.4"
+ vm_service:
+ dependency: transitive
+ description:
+ name: vm_service
+ sha256: e7fb6c2282f7631712b69c19d1bff82f3767eea33a2321c14fa59ad67ea391c7
+ url: "https://pub.dev"
+ source: hosted
+ version: "9.4.0"
+ watcher:
+ dependency: transitive
+ description:
+ name: watcher
+ sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.2"
+ webdriver:
+ dependency: transitive
+ description:
+ name: webdriver
+ sha256: ef67178f0cc7e32c1494645b11639dd1335f1d18814aa8435113a92e9ef9d841
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.1"
+ xml:
+ dependency: transitive
+ description:
+ name: xml
+ sha256: ac0e3f4bf00ba2708c33fbabbbe766300e509f8c82dbd4ab6525039813f7e2fb
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.1.0"
+ yaml:
+ dependency: transitive
+ description:
+ name: yaml
+ sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.1"
+sdks:
+ dart: ">=2.18.6 <3.0.0"
+ flutter: ">=2.11.0-0.1.pre"
diff --git a/clone-instagram-login-Refactoring/pubspec.yaml b/clone-instagram-login-Refactoring/pubspec.yaml
new file mode 100644
index 0000000..b3637b1
--- /dev/null
+++ b/clone-instagram-login-Refactoring/pubspec.yaml
@@ -0,0 +1,100 @@
+name: example_widget_testing
+description: A new Flutter project.
+
+# The following line prevents the package from being accidentally published to
+# pub.dev using `flutter pub publish`. This is preferred for private packages.
+publish_to: "none" # Remove this line if you wish to publish to pub.dev
+
+# The following defines the version and build number for your application.
+# A version number is three numbers separated by dots, like 1.2.43
+# followed by an optional build number separated by a +.
+# Both the version and the builder number may be overridden in flutter
+# build by specifying --build-name and --build-number, respectively.
+# In Android, build-name is used as versionName while build-number used as versionCode.
+# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
+# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
+# Read more about iOS versioning at
+# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
+# In Windows, build-name is used as the major, minor, and patch parts
+# of the product and file versions while build-number is used as the build suffix.
+version: 1.0.0+1
+
+environment:
+ sdk: ">=2.18.6 <3.0.0"
+
+# Dependencies specify other packages that your package needs in order to work.
+# To automatically upgrade your package dependencies to the latest versions
+# consider running `flutter pub upgrade --major-versions`. Alternatively,
+# dependencies can be manually updated by changing the version numbers below to
+# the latest version available on pub.dev. To see which dependencies have newer
+# versions available, run `flutter pub outdated`.
+dependencies:
+ flutter:
+ sdk: flutter
+
+ # The following adds the Cupertino Icons font to your application.
+ # Use with the CupertinoIcons class for iOS style icons.
+ cupertino_icons: ^1.0.2
+ flutter_svg: ^1.1.6
+
+dev_dependencies:
+ flutter_test:
+ sdk: flutter
+ integration_test:
+ sdk: flutter
+ network_image_mock: ^2.0.1
+ test_cov_console: ^0.2.2
+
+ # The "flutter_lints" package below contains a set of recommended lints to
+ # encourage good coding practices. The lint set provided by the package is
+ # activated in the `analysis_options.yaml` file located at the root of your
+ # package. See that file for information about deactivating specific lint
+ # rules and activating additional ones.
+ flutter_lints: ^2.0.0
+
+# For information on the generic Dart part of this file, see the
+# following page: https://dart.dev/tools/pub/pubspec
+
+# The following section is specific to Flutter packages.
+flutter:
+ # The following line ensures that the Material Icons font is
+ # included with your application, so that you can use the icons in
+ # the material Icons class.
+ uses-material-design: true
+
+ # To add assets to your application, add an assets section, like this:
+ assets:
+ - assets/
+ - assets/images/
+ # - 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: Billabong
+ fonts:
+ - asset: assets/fonts/Billabong.ttf
+ # 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/test.rar b/clone-instagram-login-Refactoring/test.rar
similarity index 54%
rename from test.rar
rename to clone-instagram-login-Refactoring/test.rar
index 8f18d11..f6e184d 100644
Binary files a/test.rar and b/clone-instagram-login-Refactoring/test.rar differ
diff --git a/clone-instagram-login-Refactoring/test/account_page_test.dart b/clone-instagram-login-Refactoring/test/account_page_test.dart
new file mode 100644
index 0000000..c3ce248
--- /dev/null
+++ b/clone-instagram-login-Refactoring/test/account_page_test.dart
@@ -0,0 +1,2128 @@
+import 'package:example_widget_testing/app/data/models/profile.dart';
+import 'package:example_widget_testing/app/modules/account/account_page.dart';
+import 'package:example_widget_testing/app/modules/account/components/account_name.dart';
+import 'package:example_widget_testing/app/modules/account/components/account_stat.dart';
+import 'package:example_widget_testing/app/modules/account/components/account_tab.dart';
+import 'package:example_widget_testing/app/modules/account/components/grey_button.dart';
+import 'package:example_widget_testing/app/modules/account/components/highlight_item.dart';
+import 'package:example_widget_testing/app/modules/account/components/highlight_list.dart';
+import 'package:example_widget_testing/app/modules/account/components/profile_buttons.dart';
+import 'package:example_widget_testing/app/modules/account/components/profile_information.dart';
+import 'package:example_widget_testing/app/modules/account/components/profile_pic.dart';
+import 'package:example_widget_testing/app/widgets/post_thumbnail.dart';
+import 'package:example_widget_testing/core/values/constant/post_json.dart';
+import 'package:example_widget_testing/core/values/constant/profile_json.dart';
+import 'package:example_widget_testing/core/values/constant/profile_tabs_json.dart';
+import 'package:example_widget_testing/core/values/constant/story_json.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:network_image_mock/network_image_mock.dart';
+
+import 'helper.dart';
+
+bool checkError(int index, dynamic expected, dynamic matcher) {
+ if (expected == null) {
+ debugPrint('Account Page Test-$index failed: expected is null');
+ return false;
+ }
+ try {
+ expect(expected, matcher);
+ } catch (e) {
+ debugPrint('Account Page Test-$index failed:');
+ debugPrint(e.toString());
+ return false;
+ }
+ return true;
+}
+
+final Profile profile = Profile.fromJson(profileJson);
+
+void main() {
+ final states = {};
+ testWidgets('Check if Account page Appbar is present',
+ (WidgetTester tester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ MaterialApp(
+ home: AccountPage(
+ posts: posts,
+ stories: stories,
+ profileData: profileJson,
+ ),
+ ),
+ ),
+ );
+
+ final appBarFinder = find.byKey(const Key('app_bar_account'));
+ checkError(2, appBarFinder, findsOneWidget);
+
+ final appBar = appBarFinder.evaluate().first.widget as AppBar;
+ checkError(3, appBar.backgroundColor, Colors.black);
+ checkError(4, appBar.automaticallyImplyLeading, false);
+ final appBarRowFinder = find.byKey(const Key('app_bar_row'));
+ if (checkError(5, appBarRowFinder, findsOneWidget)) {
+ final appBarRow = appBarRowFinder.evaluate().first.widget as Row;
+ checkError(
+ 6, appBarRow.mainAxisAlignment, MainAxisAlignment.spaceBetween);
+ checkError(7, appBarRow.children.length, 2);
+
+ final appBarRowNameFinder = find.byKey(const Key('app_bar_row_name'));
+ if (checkError(
+ 8,
+ find.descendant(of: appBarRowFinder, matching: appBarRowNameFinder),
+ findsOneWidget,
+ )) {
+ final appBarRowName =
+ appBarRowNameFinder.evaluate().first.widget as Row;
+ checkError(9, appBarRowName.children.length, 2);
+
+ final appBarRowNameTextFinder =
+ find.byKey(const Key('app_bar_row_name_text'));
+ if (checkError(
+ 10,
+ find.descendant(
+ of: appBarRowNameFinder, matching: appBarRowNameTextFinder),
+ findsOneWidget)) {
+ final appBarRowNameText =
+ appBarRowNameTextFinder.evaluate().first.widget as Text;
+ checkError(11, appBarRowNameText.data, 'iclop');
+ checkError(12, appBarRowNameText.style!.fontWeight, FontWeight.bold);
+
+ final appBarRowNameArrowDownIconFinder =
+ find.byKey(const Key('app_bar_row_name_arrow_down_icon'));
+ if (checkError(
+ 13,
+ find.descendant(
+ of: appBarRowNameFinder,
+ matching: appBarRowNameArrowDownIconFinder),
+ findsOneWidget)) {
+ final appBarRowNameArrowDownIcon = appBarRowNameArrowDownIconFinder
+ .evaluate()
+ .first
+ .widget as Icon;
+ checkError(
+ 14, appBarRowNameArrowDownIcon.icon, Icons.keyboard_arrow_down);
+ }
+ }
+ }
+
+ final appBarRowMenuFinder = find.byKey(const Key('app_bar_row_menu'));
+ bool appBarRowMenuIsAvailable = checkError(
+ 15,
+ find.descendant(of: appBarRowFinder, matching: appBarRowMenuFinder),
+ findsOneWidget);
+ if (appBarRowMenuIsAvailable) {
+ final appBarRowMenu =
+ appBarRowMenuFinder.evaluate().first.widget as Row;
+ checkError(16, appBarRowMenu.children.length, 3);
+
+ final appBarRowMenuUploadIconFinder =
+ find.byKey(const Key('app_bar_row_menu_upload_icon'));
+ bool appBarRowMenuUploadIconIsAvailable = checkError(
+ 17,
+ find.descendant(
+ of: appBarRowMenuFinder,
+ matching: appBarRowMenuUploadIconFinder),
+ findsOneWidget);
+ bool appBarRowMenuUploadIconIsSvgPicture = checkError(
+ 18,
+ appBarRowMenuUploadIconFinder.evaluate().first.widget,
+ isA());
+ if (appBarRowMenuUploadIconIsAvailable &&
+ appBarRowMenuUploadIconIsSvgPicture) {
+ final appBarRowMenuUploadIcon = appBarRowMenuUploadIconFinder
+ .evaluate()
+ .first
+ .widget as SvgPicture;
+ checkError(19, appBarRowMenuUploadIcon.width, 27);
+ bool appBarRowMenuUploadIconIsAssetPicture = checkError(
+ 20,
+ appBarRowMenuUploadIcon.pictureProvider.runtimeType,
+ ExactAssetPicture);
+ if (appBarRowMenuUploadIconIsAssetPicture) {
+ final appBarRowMenuUploadIconAssetPicture =
+ appBarRowMenuUploadIcon.pictureProvider as ExactAssetPicture;
+ checkError(21, appBarRowMenuUploadIconAssetPicture.assetName,
+ "assets/images/upload_icon.svg");
+ }
+ }
+
+ final appBarRowMenuHamburgerIconFinder =
+ find.byKey(const Key('app_bar_row_menu_hamburger_icon'));
+ bool appBarRowMenuHamburgerIconIsAvailable = checkError(
+ 22,
+ find.descendant(
+ of: appBarRowMenuFinder,
+ matching: appBarRowMenuHamburgerIconFinder),
+ findsOneWidget);
+ bool appBarRowMenuHamburgerIconIsIcon = checkError(
+ 23,
+ appBarRowMenuHamburgerIconFinder.evaluate().first.widget,
+ isA());
+ if (appBarRowMenuHamburgerIconIsAvailable &&
+ appBarRowMenuHamburgerIconIsIcon) {
+ final appBarRowMenuHamburgerIcon =
+ appBarRowMenuHamburgerIconFinder.evaluate().first.widget as Icon;
+ checkError(24, appBarRowMenuHamburgerIcon.size, 35);
+ checkError(25, appBarRowMenuHamburgerIcon.icon, Icons.menu);
+ }
+ }
+ }
+ });
+ testWidgets("Check if Account page body is present", (widgetTester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+
+ await mockNetworkImagesFor(
+ () => widgetTester.pumpWidget(
+ MaterialApp(
+ home: AccountPage(
+ posts: posts,
+ stories: stories,
+ profileData: profileJson,
+ ),
+ ),
+ ),
+ );
+
+ final accountPageListViewFinder = find.byKey(
+ const Key('account_page_listview'),
+ );
+ checkError(26, accountPageListViewFinder, findsOneWidget);
+
+ final accountStatFinder = find.byKey(const Key('account_stat'));
+ checkError(27, accountStatFinder, findsOneWidget);
+
+ final accountNameFinder = find.byKey(const Key('account_name'));
+ checkError(28, accountNameFinder, findsOneWidget);
+
+ final profileButtons = find.byKey(const Key('profile_buttons'));
+ checkError(29, profileButtons, findsOneWidget);
+
+ final highlightList = find.byKey(const Key('highlight_list'));
+ checkError(30, highlightList, findsOneWidget);
+
+ final accountTab = find.byKey(const Key('account_tab'));
+ checkError(31, accountTab, findsOneWidget);
+
+ final accountPagePostWrapFinder =
+ find.byKey(const Key('account_page_post_wrap'));
+ bool isAccountPagePostWrapAvailable = checkError(
+ 32,
+ accountPagePostWrapFinder,
+ findsOneWidget,
+ );
+ if (isAccountPagePostWrapAvailable) {
+ final accountPagePostWrap =
+ accountPagePostWrapFinder.evaluate().first.widget as Wrap;
+ checkError(33, accountPagePostWrap.spacing, 1.5);
+ checkError(34, accountPagePostWrap.runSpacing, 1.5);
+ checkError(35, accountPagePostWrap.children.length, posts.length);
+ posts.asMap().forEach((key, value) {
+ final accountPostInkWellFinder = find.byKey(
+ Key('account_post_inkwell_$key'),
+ );
+ bool isAccountPostInkWellAvailable = checkError(
+ 351,
+ accountPostInkWellFinder,
+ findsOneWidget,
+ );
+ if (isAccountPostInkWellAvailable) {
+ checkError(
+ 352,
+ accountPostInkWellFinder.evaluate().first.widget,
+ isA(),
+ );
+ final accountPostThumbnailFinder = find.byKey(
+ Key('account_post_thumbnail_$key'),
+ );
+ bool isAccountPostThumbnailAvailable = checkError(
+ 353,
+ accountPostThumbnailFinder,
+ findsOneWidget,
+ );
+ if (isAccountPostThumbnailAvailable) {
+ bool accountPostThumbnailIsPostThumbnail = checkError(
+ 354,
+ accountPostThumbnailFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (accountPostThumbnailIsPostThumbnail) {
+ final accountPostThumbnail = accountPostThumbnailFinder
+ .evaluate()
+ .first
+ .widget as PostThumbnail;
+ checkError(
+ 355,
+ accountPostThumbnail.imageUrl,
+ posts[key]['postImg'],
+ );
+ }
+ }
+ }
+ });
+ }
+ });
+ testWidgets("Check if account stats is present", (widgetTester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+
+ await mockNetworkImagesFor(
+ () => widgetTester.pumpWidget(
+ MaterialApp(
+ home: AccountStat(profile: profile),
+ ),
+ ),
+ );
+
+ final accountPageProfileRowFinder =
+ find.byKey(const Key('account_page_profile_row'));
+ bool accounntPageListViewIsAvailable = checkError(
+ 26,
+ accountPageProfileRowFinder,
+ findsOneWidget,
+ );
+ bool accounntPageListViewIsRow = checkError(
+ 27,
+ accountPageProfileRowFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (accounntPageListViewIsAvailable && accounntPageListViewIsRow) {
+ final accountPageProfileRow =
+ accountPageProfileRowFinder.evaluate().first.widget as Row;
+ checkError(28, accountPageProfileRow.children.length, 2);
+
+ final profilePicFinder = find.byKey(const Key('profile_pic'));
+ checkError(29, profilePicFinder, findsOneWidget);
+
+ final accountPageProfileInformationExpandedFinder = find.byKey(
+ const Key('account_page_profile_information_expanded'),
+ );
+ bool accountPageProfileInformationExpandedIsAvailable = checkError(
+ 30,
+ accountPageProfileInformationExpandedFinder,
+ findsOneWidget,
+ );
+
+ checkError(
+ 31,
+ accountPageProfileInformationExpandedFinder.evaluate().first.widget,
+ isA(),
+ );
+
+ if (accountPageProfileInformationExpandedIsAvailable) {
+ final profileInformationFinder = find.byKey(
+ const Key('profile_information'),
+ );
+ checkError(
+ 32,
+ find.descendant(
+ of: accountPageProfileInformationExpandedFinder,
+ matching: profileInformationFinder,
+ ),
+ findsOneWidget,
+ );
+ }
+ }
+ });
+ testWidgets("Check if profile picture is rendered correctly",
+ (widgetTester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+
+ await mockNetworkImagesFor(
+ () => widgetTester.pumpWidget(
+ MaterialApp(
+ home: ProfilePic(pictureUrl: profile.profilePic!),
+ ),
+ ),
+ );
+
+ final profilePicContainerFinder = find.byKey(
+ const Key('profile_pic_container'),
+ );
+ bool profilePicContainerIsAvailable = checkError(
+ 33,
+ profilePicContainerFinder,
+ findsOneWidget,
+ );
+ if (profilePicContainerIsAvailable) {
+ bool profilePicContainerIsContainer = checkError(
+ 34,
+ profilePicContainerFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (profilePicContainerIsContainer) {
+ final profilePicContainer =
+ profilePicContainerFinder.evaluate().first.widget as Container;
+ checkError(
+ 35,
+ profilePicContainer.constraints!.widthConstraints(),
+ const BoxConstraints(minWidth: 80, maxWidth: 80),
+ );
+ checkError(
+ 36,
+ profilePicContainer.constraints!.heightConstraints(),
+ const BoxConstraints(minHeight: 80, maxHeight: 80),
+ );
+ checkError(
+ 37,
+ profilePicContainer.margin,
+ const EdgeInsets.only(left: 15, right: 30),
+ );
+ final profilePicDecoration =
+ profilePicContainer.decoration as BoxDecoration;
+ bool profilePicDecorationIsBoxDecoration = checkError(
+ 38,
+ profilePicDecoration,
+ isA(),
+ );
+
+ if (profilePicDecorationIsBoxDecoration) {
+ final profilePicDecoration =
+ profilePicContainer.decoration as BoxDecoration;
+ checkError(
+ 39,
+ profilePicDecoration.shape,
+ BoxShape.circle,
+ );
+
+ bool profilePicDecorationImageIsDecorationImage = checkError(
+ 40,
+ profilePicDecoration.image,
+ isA(),
+ );
+ if (profilePicDecorationImageIsDecorationImage) {
+ final profilePicDecorationImage =
+ profilePicDecoration.image as DecorationImage;
+ checkError(41, profilePicDecorationImage.fit, BoxFit.cover);
+ bool profilePicDecorationImageIsNetworkImage = checkError(
+ 42,
+ profilePicDecorationImage.image,
+ isA(),
+ );
+ if (profilePicDecorationImageIsNetworkImage) {
+ final profilePicDecorationImageNetworkImage =
+ profilePicDecorationImage.image as NetworkImage;
+ checkError(
+ 43,
+ profilePicDecorationImageNetworkImage.url,
+ profile.profilePic!,
+ );
+ }
+ }
+ }
+ }
+ }
+ });
+ testWidgets("Check if profile informations is rendered correctly",
+ (widgetTester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+
+ await mockNetworkImagesFor(
+ () => widgetTester.pumpWidget(
+ MaterialApp(
+ home: ProfileInformation(profileStats: profile.stats!),
+ ),
+ ),
+ );
+
+ final profileInformationRowFinder = find.byKey(
+ const Key('profile_information_row'),
+ );
+ bool profileInformationRowIsAvailable = checkError(
+ 44,
+ profileInformationRowFinder,
+ findsOneWidget,
+ );
+ if (profileInformationRowIsAvailable) {
+ bool profileInformationRowIsRow = checkError(
+ 45, profileInformationRowFinder.evaluate().first.widget, isA());
+ if (profileInformationRowIsRow) {
+ final profileInformationRow =
+ profileInformationRowFinder.evaluate().first.widget as Row;
+ checkError(
+ 46, profileInformationRow.children.length, profile.stats!.length);
+ checkError(
+ 47,
+ profileInformationRow.mainAxisAlignment,
+ MainAxisAlignment.spaceAround,
+ );
+
+ profile.stats!.asMap().forEach((index, value) {
+ final profileInformationColumnFinder = find.byKey(
+ Key('profile_information_column_$index'),
+ );
+ bool profileInformationColumnIsAvailable = checkError(
+ 48,
+ profileInformationColumnFinder,
+ findsOneWidget,
+ );
+ if (profileInformationColumnIsAvailable) {
+ bool profileInformationColumnIsColumn = checkError(
+ 49,
+ profileInformationColumnFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (profileInformationColumnIsColumn) {
+ final profileInformationColumn = profileInformationColumnFinder
+ .evaluate()
+ .first
+ .widget as Column;
+ checkError(50, profileInformationColumn.children.length, 2);
+
+ final profileInformationAmountTextFinder = find.byKey(
+ Key('profile_information_${index}_amount_text'),
+ );
+ bool profileInformationAmountTextIsAvailable = checkError(
+ 51,
+ profileInformationAmountTextFinder,
+ findsOneWidget,
+ );
+ if (profileInformationAmountTextIsAvailable) {
+ bool profileInformationAmountTextIsText = checkError(
+ 52,
+ profileInformationAmountTextFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (profileInformationAmountTextIsText) {
+ final profileInformationAmountText =
+ profileInformationAmountTextFinder.evaluate().first.widget
+ as Text;
+ checkError(53, profileInformationAmountText.data,
+ profile.stats![index].count.toString());
+ checkError(
+ 54,
+ profileInformationAmountText.style,
+ const TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.w700,
+ color: Colors.white),
+ );
+ }
+ }
+
+ final profileInformationLabelTextFinder = find.byKey(
+ Key('profile_information_${index}_label_text'),
+ );
+ bool profileInformationLabelTextIsAvailable = checkError(
+ 55,
+ profileInformationLabelTextFinder,
+ findsOneWidget,
+ );
+ if (profileInformationLabelTextIsAvailable) {
+ bool profileInformationLabelTextIsText = checkError(
+ 56,
+ profileInformationLabelTextFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (profileInformationLabelTextIsText) {
+ final profileInformationLabelText =
+ profileInformationLabelTextFinder.evaluate().first.widget
+ as Text;
+ checkError(57, profileInformationLabelText.data,
+ profile.stats![index].label);
+ checkError(
+ 58,
+ profileInformationLabelText.style,
+ const TextStyle(
+ fontSize: 15,
+ fontWeight: FontWeight.w400,
+ color: Colors.white,
+ ),
+ );
+ }
+ }
+ }
+ }
+ });
+ }
+ }
+ });
+ testWidgets("Check if account's name is rendered correctly",
+ (widgetTester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+
+ await mockNetworkImagesFor(
+ () => widgetTester.pumpWidget(
+ MaterialApp(
+ home: AccountName(profile: profile),
+ ),
+ ),
+ );
+
+ final accountNameContainerFinder = find.byKey(
+ const Key('account_name_container'),
+ );
+ bool accountNameContainerIsAvailable = checkError(
+ 59,
+ accountNameContainerFinder,
+ findsOneWidget,
+ );
+ if (accountNameContainerIsAvailable) {
+ bool accountNameContainerIsContainer = checkError(
+ 60,
+ accountNameContainerFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (accountNameContainerIsContainer) {
+ final accountNameContainer =
+ accountNameContainerFinder.evaluate().first.widget as Container;
+ checkError(
+ 61,
+ accountNameContainer.constraints!.widthConstraints(),
+ const BoxConstraints(
+ minWidth: double.infinity, maxWidth: double.infinity),
+ );
+ checkError(
+ 62,
+ accountNameContainer.padding,
+ const EdgeInsets.symmetric(horizontal: 15),
+ );
+ checkError(
+ 63,
+ accountNameContainer.margin,
+ const EdgeInsets.symmetric(vertical: 10),
+ );
+
+ final accountNameColumnFinder = find.byKey(
+ const Key('account_name_column'),
+ );
+ bool accountNameColumnIsAvailable = checkError(
+ 64,
+ find.descendant(
+ of: accountNameContainerFinder,
+ matching: accountNameColumnFinder),
+ findsOneWidget,
+ );
+
+ if (accountNameColumnIsAvailable) {
+ bool accountNameColumnIsColumn = checkError(
+ 65,
+ accountNameColumnFinder.evaluate().first.widget,
+ isA(),
+ );
+
+ if (accountNameColumnIsColumn) {
+ final accountNameColumn =
+ accountNameColumnFinder.evaluate().first.widget as Column;
+ checkError(
+ 66,
+ accountNameColumn.crossAxisAlignment,
+ CrossAxisAlignment.start,
+ );
+ checkError(67, accountNameColumn.children.length, 2);
+
+ final accountNameTextFinder = find.byKey(
+ const Key('account_name_text'),
+ );
+
+ bool accountNameTextIsAvailable = checkError(
+ 68,
+ find.descendant(
+ of: accountNameColumnFinder, matching: accountNameTextFinder),
+ findsOneWidget,
+ );
+
+ if (accountNameTextIsAvailable) {
+ bool accountNameTextIsText = checkError(
+ 69,
+ accountNameTextFinder.evaluate().first.widget,
+ isA(),
+ );
+
+ if (accountNameTextIsText) {
+ final accountNameText =
+ accountNameTextFinder.evaluate().first.widget as Text;
+ checkError(70, accountNameText.data, profile.name);
+ checkError(
+ 71,
+ accountNameText.style,
+ const TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.w400,
+ color: Colors.white,
+ ),
+ );
+ }
+ }
+
+ final accountBioText = find.byKey(const Key('account_bio_text'));
+ bool accountBioTextIsAvailable = checkError(
+ 72,
+ find.descendant(
+ of: accountNameColumnFinder, matching: accountBioText),
+ findsOneWidget,
+ );
+
+ if (accountBioTextIsAvailable) {
+ bool accountBioTextIsText = checkError(
+ 73,
+ accountBioText.evaluate().first.widget,
+ isA(),
+ );
+
+ if (accountBioTextIsText) {
+ final accountBioTextWidget =
+ accountBioText.evaluate().first.widget as Text;
+ checkError(74, accountBioTextWidget.data, profile.bio);
+ checkError(
+ 75,
+ accountBioTextWidget.style,
+ const TextStyle(
+ fontSize: 15,
+ fontWeight: FontWeight.w400,
+ color: Colors.white,
+ ),
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+ });
+ testWidgets("Check if profile buttons is rendered correctly",
+ (widgetTester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+
+ await mockNetworkImagesFor(
+ () => widgetTester.pumpWidget(
+ const MaterialApp(
+ home: ProfileButtons(),
+ ),
+ ),
+ );
+
+ final profileButtonsPaddingFinder = find.byKey(
+ const Key('profile_buttons_padding'),
+ );
+
+ bool accountPageProfileButtonsPaddingIsAvailable = checkError(
+ 76,
+ profileButtonsPaddingFinder,
+ findsOneWidget,
+ );
+
+ if (accountPageProfileButtonsPaddingIsAvailable) {
+ bool accountPageProfileButtonsPaddingIsPadding = checkError(
+ 77,
+ profileButtonsPaddingFinder.evaluate().first.widget,
+ isA(),
+ );
+
+ if (accountPageProfileButtonsPaddingIsPadding) {
+ final accountPageProfileButtonsPadding =
+ profileButtonsPaddingFinder.evaluate().first.widget as Padding;
+ checkError(
+ 78,
+ accountPageProfileButtonsPadding.padding,
+ const EdgeInsets.symmetric(horizontal: 15),
+ );
+
+ final profileButtonsRowFinder =
+ find.byKey(const Key('profile_buttons_row'));
+ bool profileButtonsRowIsAvailable = checkError(
+ 79,
+ find.descendant(
+ of: profileButtonsPaddingFinder,
+ matching: profileButtonsRowFinder),
+ findsOneWidget,
+ );
+
+ if (profileButtonsRowIsAvailable) {
+ bool profileButtonsRowIsRow = checkError(
+ 80,
+ profileButtonsRowFinder.evaluate().first.widget,
+ isA(),
+ );
+
+ if (profileButtonsRowIsRow) {
+ final profileButtonsRow =
+ profileButtonsRowFinder.evaluate().first.widget as Row;
+ checkError(
+ 81,
+ profileButtonsRow.mainAxisAlignment,
+ MainAxisAlignment.spaceBetween,
+ );
+ checkError(82, profileButtonsRow.children.length, 5);
+
+ final profileButtonsEditProfileButtonExpandedFinder = find.byKey(
+ const Key('profile_buttons_edit_profile_button_expanded'),
+ );
+ bool profileButtonsEditProfileButtonExpandedIsAvailable =
+ checkError(
+ 83,
+ find.descendant(
+ of: profileButtonsRowFinder,
+ matching: profileButtonsEditProfileButtonExpandedFinder,
+ ),
+ findsOneWidget,
+ );
+
+ if (profileButtonsEditProfileButtonExpandedIsAvailable) {
+ checkError(
+ 84,
+ profileButtonsEditProfileButtonExpandedFinder
+ .evaluate()
+ .first
+ .widget,
+ isA(),
+ );
+
+ final profileButtonsEditProfileButtonFinder = find.byKey(
+ const Key('profile_buttons_edit_profile_button'),
+ );
+ bool profileButtonsEditProfileButtonIsAvailable = checkError(
+ 85,
+ find.descendant(
+ of: profileButtonsEditProfileButtonExpandedFinder,
+ matching: profileButtonsEditProfileButtonFinder),
+ findsOneWidget,
+ );
+ if (profileButtonsEditProfileButtonIsAvailable) {
+ checkError(
+ 86,
+ profileButtonsEditProfileButtonFinder.evaluate().first.widget,
+ isA(),
+ );
+
+ final profileButtonsEditProfileButtonTextFinder = find.byKey(
+ const Key('profile_buttons_edit_profile_button_text'),
+ );
+ bool profileButtonsEditProfileButtonTextIsAvailable =
+ checkError(
+ 87,
+ find.descendant(
+ of: profileButtonsEditProfileButtonFinder,
+ matching: profileButtonsEditProfileButtonTextFinder),
+ findsOneWidget,
+ );
+ if (profileButtonsEditProfileButtonTextIsAvailable) {
+ bool profileButtonsEditProfileButtonTextIsText = checkError(
+ 88,
+ profileButtonsEditProfileButtonTextFinder
+ .evaluate()
+ .first
+ .widget,
+ isA(),
+ );
+ if (profileButtonsEditProfileButtonTextIsText) {
+ final profileButtonsEditProfileButtonText =
+ profileButtonsEditProfileButtonTextFinder
+ .evaluate()
+ .first
+ .widget as Text;
+ checkError(
+ 89,
+ profileButtonsEditProfileButtonText.data,
+ 'Edit Profile',
+ );
+ checkError(
+ 90,
+ profileButtonsEditProfileButtonText.style,
+ const TextStyle(
+ fontSize: 15,
+ fontWeight: FontWeight.w500,
+ color: Colors.white,
+ ),
+ );
+ }
+ }
+ }
+ }
+
+ final profileButtonsShareProfileButtonExpandedFinder = find.byKey(
+ const Key('profile_buttons_share_profile_button_expanded'),
+ );
+ bool profileButtonsShareProfileButtonExpandedIsAvailable =
+ checkError(
+ 91,
+ find.descendant(
+ of: profileButtonsRowFinder,
+ matching: profileButtonsShareProfileButtonExpandedFinder,
+ ),
+ findsOneWidget,
+ );
+ if (profileButtonsShareProfileButtonExpandedIsAvailable) {
+ checkError(
+ 92,
+ profileButtonsShareProfileButtonExpandedFinder
+ .evaluate()
+ .first
+ .widget,
+ isA(),
+ );
+
+ final profileButtonsShareProfileButtonFinder = find.byKey(
+ const Key('profile_buttons_share_profile_button'),
+ );
+ bool profileButtonsShareProfileButtonIsAvailable = checkError(
+ 93,
+ find.descendant(
+ of: profileButtonsShareProfileButtonExpandedFinder,
+ matching: profileButtonsShareProfileButtonFinder),
+ findsOneWidget,
+ );
+ if (profileButtonsShareProfileButtonIsAvailable) {
+ checkError(
+ 94,
+ profileButtonsShareProfileButtonFinder
+ .evaluate()
+ .first
+ .widget,
+ isA(),
+ );
+
+ final profileButtonsShareProfileButtonTextFinder = find.byKey(
+ const Key('profile_buttons_share_profile_button_text'),
+ );
+ bool profileButtonsShareProfileButtonTextIsAvailable =
+ checkError(
+ 95,
+ find.descendant(
+ of: profileButtonsShareProfileButtonFinder,
+ matching: profileButtonsShareProfileButtonTextFinder),
+ findsOneWidget,
+ );
+ if (profileButtonsShareProfileButtonTextIsAvailable) {
+ bool profileButtonsShareProfileButtonTextIsText = checkError(
+ 96,
+ profileButtonsShareProfileButtonTextFinder
+ .evaluate()
+ .first
+ .widget,
+ isA(),
+ );
+ if (profileButtonsShareProfileButtonTextIsText) {
+ final profileButtonsShareProfileButtonText =
+ profileButtonsShareProfileButtonTextFinder
+ .evaluate()
+ .first
+ .widget as Text;
+ checkError(
+ 97,
+ profileButtonsShareProfileButtonText.data,
+ 'Share profile',
+ );
+ checkError(
+ 98,
+ profileButtonsShareProfileButtonText.style,
+ const TextStyle(
+ fontSize: 15,
+ fontWeight: FontWeight.w500,
+ color: Colors.white,
+ ),
+ );
+ }
+ }
+ }
+ }
+
+ final profileButtonsDiscoverPeopleButtonFinder = find.byKey(
+ const Key('profile_buttons_discover_people_button'),
+ );
+ bool profileButtonsDiscoverPeopleButtonIsAvailable = checkError(
+ 99,
+ find.descendant(
+ of: profileButtonsRowFinder,
+ matching: profileButtonsDiscoverPeopleButtonFinder),
+ findsOneWidget,
+ );
+ if (profileButtonsDiscoverPeopleButtonIsAvailable) {
+ checkError(
+ 100,
+ profileButtonsDiscoverPeopleButtonFinder
+ .evaluate()
+ .first
+ .widget,
+ isA(),
+ );
+
+ final profileButtonsDiscoverPeopleIconFinder = find.byKey(
+ const Key('profile_buttons_discover_people_icon'),
+ );
+ bool profileButtonsDiscoverPeopleIconIsAvailable = checkError(
+ 101,
+ find.descendant(
+ of: profileButtonsDiscoverPeopleButtonFinder,
+ matching: profileButtonsDiscoverPeopleIconFinder),
+ findsOneWidget,
+ );
+ if (profileButtonsDiscoverPeopleIconIsAvailable) {
+ bool profileButtonsDiscoverPeopleIconIsIcon = checkError(
+ 102,
+ profileButtonsDiscoverPeopleIconFinder
+ .evaluate()
+ .first
+ .widget,
+ isA(),
+ );
+ if (profileButtonsDiscoverPeopleIconIsIcon) {
+ final profileButtonsDiscoverPeopleIcon =
+ profileButtonsDiscoverPeopleIconFinder
+ .evaluate()
+ .first
+ .widget as Icon;
+ checkError(
+ 103,
+ profileButtonsDiscoverPeopleIcon.icon,
+ Icons.person_add_outlined,
+ );
+ checkError(
+ 104,
+ profileButtonsDiscoverPeopleIcon.color,
+ Colors.white,
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ });
+ testWidgets("Check if Grey buttons is rendered correctly",
+ (widgetTester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+ const mockKey = Key('grey_button');
+ const mockWidget = Text('Grey Button');
+
+ await mockNetworkImagesFor(
+ () => widgetTester.pumpWidget(
+ MaterialApp(
+ home: GreyButton(
+ key: mockKey,
+ onPressed: () {},
+ child: mockWidget,
+ ),
+ ),
+ ),
+ );
+
+ final greyButtonElevatedButtonFinder = find.byKey(
+ Key('${mockKey}_elevated_button'),
+ );
+ bool greyButtonElevatedButtonIsAvailable = checkError(
+ 105,
+ greyButtonElevatedButtonFinder,
+ findsOneWidget,
+ );
+ if (greyButtonElevatedButtonIsAvailable) {
+ bool greyButtonElevatedButtonIsElevatedButton = checkError(
+ 106,
+ greyButtonElevatedButtonFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (greyButtonElevatedButtonIsElevatedButton) {
+ final greyButtonElevatedButton = greyButtonElevatedButtonFinder
+ .evaluate()
+ .first
+ .widget as ElevatedButton;
+ try {
+ checkError(
+ 107,
+ greyButtonElevatedButton.style!.backgroundColor!.resolve(states),
+ Colors.grey[800],
+ );
+ } catch (e) {
+ debugPrint(
+ "Account Page Test-107 failed: backgroundColor is not set",
+ );
+ }
+
+ try {
+ checkError(
+ 108,
+ greyButtonElevatedButton.style!.minimumSize!.resolve(states),
+ const Size(0, 30),
+ );
+ } catch (e) {
+ debugPrint(
+ "Account Page Test-108 failed: minimumSize is not set",
+ );
+ }
+
+ try {
+ checkError(
+ 109,
+ greyButtonElevatedButton.style!.shape!.resolve(states),
+ RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(5),
+ ),
+ );
+ } catch (e) {
+ debugPrint(
+ "Account Page Test-109 failed: shape is not set",
+ );
+ }
+ }
+ }
+ });
+ testWidgets("Check if Highlight list is rendered correctly",
+ (widgetTester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+
+ await mockNetworkImagesFor(
+ () => widgetTester.pumpWidget(
+ MaterialApp(
+ home: HighlightList(stories: stories),
+ ),
+ ),
+ );
+
+ final highlightListScrollViewFinder = find.byKey(
+ const Key('highlight_list_scroll_view'),
+ );
+
+ bool highlightListScrollViewIsAvailable = checkError(
+ 110,
+ highlightListScrollViewFinder,
+ findsOneWidget,
+ );
+
+ if (highlightListScrollViewIsAvailable) {
+ bool highlightListScrollViewIsScrollView = checkError(
+ 111,
+ highlightListScrollViewFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (highlightListScrollViewIsScrollView) {
+ final highlightListScrollView = highlightListScrollViewFinder
+ .evaluate()
+ .first
+ .widget as SingleChildScrollView;
+ checkError(
+ 112,
+ highlightListScrollView.scrollDirection,
+ Axis.horizontal,
+ );
+ checkError(
+ 113,
+ highlightListScrollView.padding,
+ const EdgeInsets.only(left: 15, top: 10, bottom: 10),
+ );
+ }
+ final highlightListParentRowFinder = find.byKey(
+ const Key("highlight_list_parent_row"),
+ );
+ bool highlightListParentRowIsAvailable = checkError(
+ 114,
+ find.descendant(
+ of: highlightListScrollViewFinder,
+ matching: highlightListParentRowFinder,
+ ),
+ findsOneWidget,
+ );
+ if (highlightListParentRowIsAvailable) {
+ checkError(
+ 115,
+ highlightListParentRowFinder.evaluate().first.widget,
+ isA(),
+ );
+ final highlightListChildRowFinder = find.byKey(
+ const Key("highlight_list_child_row"),
+ );
+ bool highlightListChildRowIsAvailable = checkError(
+ 116,
+ find.descendant(
+ of: highlightListParentRowFinder,
+ matching: highlightListChildRowFinder,
+ ),
+ findsOneWidget,
+ );
+ if (highlightListChildRowIsAvailable) {
+ bool highlightListChildRowIsRow = checkError(
+ 117,
+ highlightListChildRowFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (highlightListChildRowIsRow) {
+ final highlightListChildRow =
+ highlightListChildRowFinder.evaluate().first.widget as Row;
+ bool highlightItemsFinder = checkError(
+ 118,
+ highlightListChildRow.children.length,
+ stories.length,
+ );
+
+ if (highlightItemsFinder) {
+ stories.asMap().forEach((key, value) {
+ final highlightItemFinder = find.byKey(
+ Key("highlight_item_$key"),
+ );
+ bool highlightItemIsAvailable = checkError(
+ 119,
+ find.descendant(
+ of: highlightListChildRowFinder,
+ matching: highlightItemFinder,
+ ),
+ findsOneWidget,
+ );
+
+ if (highlightItemIsAvailable) {
+ bool highlightItemIsHighlightItem = checkError(
+ 120,
+ highlightItemFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (highlightItemIsHighlightItem) {
+ final highlightItem = highlightItemFinder
+ .evaluate()
+ .first
+ .widget as HighlightItem;
+ checkError(
+ 121,
+ highlightItem.img,
+ value["img"],
+ );
+ checkError(
+ 122,
+ highlightItem.name,
+ value["name"],
+ );
+ }
+ }
+ });
+ }
+ }
+ }
+
+ final highightListAddHighlightFinder = find.byKey(
+ const Key("highlight_list_add_highlight"),
+ );
+ bool highightAddHighlightIsAvailable = checkError(
+ 123,
+ find.descendant(
+ of: highlightListParentRowFinder,
+ matching: highightListAddHighlightFinder,
+ ),
+ findsOneWidget,
+ );
+
+ if (highightAddHighlightIsAvailable) {
+ bool highightAddHighlightIsPadding = checkError(
+ 124,
+ highightListAddHighlightFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (highightAddHighlightIsPadding) {
+ final highightAddHighlight = highightListAddHighlightFinder
+ .evaluate()
+ .first
+ .widget as Padding;
+ checkError(
+ 125,
+ highightAddHighlight.padding,
+ const EdgeInsets.only(right: 10, bottom: 10),
+ );
+ }
+
+ final highlightListAddHighlightColumnFinder = find.byKey(
+ const Key("highlight_list_add_highlight_column"),
+ );
+ bool highlightListAddHighlightColumnIsAvailable = checkError(
+ 126,
+ find.descendant(
+ of: highightListAddHighlightFinder,
+ matching: highlightListAddHighlightColumnFinder,
+ ),
+ findsOneWidget,
+ );
+ if (highlightListAddHighlightColumnIsAvailable) {
+ bool highlightListAddHighlightColumnIsColumn = checkError(
+ 127,
+ highlightListAddHighlightColumnFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (highlightListAddHighlightColumnIsColumn) {
+ final highlightListAddHighlightColumn =
+ highlightListAddHighlightColumnFinder.evaluate().first.widget
+ as Column;
+ checkError(
+ 129,
+ highlightListAddHighlightColumn.children.length,
+ 2,
+ );
+ // final highlightListAddHighlightIconFinder = find.byKey(
+ // const Key("highlight_list_add_highlight_icon"),
+ // );
+ // bool highlightListAddHighlightIconIsAvailable = checkError(
+ // 130,
+ // find.descendant(
+ // of: highlightListAddHighlightColumnFinder,
+ // matching: highlightListAddHighlightIconFinder,
+ // ),
+ // findsOneWidget,
+ // );
+ // if (highlightListAddHighlightIconIsAvailable) {
+ // bool highlightListAddHighlightIconIsIcon = checkError(
+ // 131,
+ // highlightListAddHighlightIconFinder.evaluate().first.widget,
+ // isA(),
+ // );
+ // if (highlightListAddHighlightIconIsIcon) {
+ // final highlightListAddHighlightIcon =
+ // highlightListAddHighlightIconFinder
+ // .evaluate()
+ // .first
+ // .widget as Icon;
+ // checkError(
+ // 132,
+ // highlightListAddHighlightIcon.icon,
+ // Icons.add,
+ // );
+ // checkError(
+ // 133,
+ // highlightListAddHighlightIcon.color,
+ // Colors.white,
+ // );
+ // }
+ // }
+ // final highlightListAddHighlightTextFinder = find.byKey(
+ // const Key("highlight_list_add_highlight_text"),
+ // );
+ // bool highlightListAddHighlightTextIsAvailable = checkError(
+ // 134,
+ // find.descendant(
+ // of: highlightListAddHighlightColumnFinder,
+ // matching: highlightListAddHighlightTextFinder,
+ // ),
+ // findsOneWidget,
+ // );
+ // if (highlightListAddHighlightTextIsAvailable) {
+ // bool highlightListAddHighlightTextIsText = checkError(
+ // 135,
+ // highlightListAddHighlightTextFinder.evaluate().first.widget,
+ // isA(),
+ // );
+ // if (highlightListAddHighlightTextIsText) {
+ // final highlightListAddHighlightText =
+ // highlightListAddHighlightTextFinder
+ // .evaluate()
+ // .first
+ // .widget as Text;
+ // checkError(
+ // 136,
+ // highlightListAddHighlightText.data,
+ // "New",
+ // );
+ // }
+ // }
+ }
+
+ final highlightListAddHighlightContainerFinder = find.byKey(
+ const Key("highlight_list_add_highlight_container"),
+ );
+ bool highlightAddHighlightContainerIsAvailable = checkError(
+ 137,
+ find.descendant(
+ of: highlightListAddHighlightColumnFinder,
+ matching: highlightListAddHighlightContainerFinder,
+ ),
+ findsOneWidget,
+ );
+ if (highlightAddHighlightContainerIsAvailable) {
+ bool highlightAddHighlightContainerIsContainer = checkError(
+ 138,
+ highlightListAddHighlightContainerFinder
+ .evaluate()
+ .first
+ .widget,
+ isA(),
+ );
+ if (highlightAddHighlightContainerIsContainer) {
+ final highlightAddHighlightContainer =
+ highlightListAddHighlightContainerFinder
+ .evaluate()
+ .first
+ .widget as Container;
+ checkError(
+ 139,
+ highlightAddHighlightContainer.padding,
+ const EdgeInsets.all(3),
+ );
+ checkError(
+ 140,
+ highlightAddHighlightContainer.margin,
+ const EdgeInsets.only(bottom: 8),
+ );
+ checkError(
+ 141,
+ highlightAddHighlightContainer.constraints!
+ .widthConstraints(),
+ const BoxConstraints(minWidth: 68, maxWidth: 68),
+ );
+ checkError(
+ 142,
+ highlightAddHighlightContainer.constraints!
+ .heightConstraints(),
+ const BoxConstraints(minHeight: 68, maxHeight: 68),
+ );
+
+ bool highlightAddHighlightContainerDecorationBoxDecoration =
+ checkError(
+ 143,
+ highlightAddHighlightContainer.decoration,
+ isA(),
+ );
+ if (highlightAddHighlightContainerDecorationBoxDecoration) {
+ final highlightAddHighlightContainerDecoration =
+ highlightAddHighlightContainer.decoration
+ as BoxDecoration;
+ checkError(
+ 144,
+ highlightAddHighlightContainerDecoration.shape,
+ BoxShape.circle);
+ checkError(
+ 145,
+ highlightAddHighlightContainerDecoration.border,
+ Border.all(color: Colors.white, width: 1),
+ );
+ }
+ }
+
+ final highlightListAddHighlightIconContainerFinder = find.byKey(
+ const Key("highlight_list_add_highlight_icon_container"),
+ );
+
+ bool highlightListAddHighlightIconContainerIsAvailable =
+ checkError(
+ 146,
+ find.descendant(
+ of: highlightListAddHighlightContainerFinder,
+ matching: highlightListAddHighlightIconContainerFinder,
+ ),
+ findsOneWidget,
+ );
+ if (highlightListAddHighlightIconContainerIsAvailable) {
+ bool highlightListAddHighlightIconContainerIsContainer =
+ checkError(
+ 147,
+ highlightListAddHighlightIconContainerFinder
+ .evaluate()
+ .first
+ .widget,
+ isA(),
+ );
+ if (highlightListAddHighlightIconContainerIsContainer) {
+ final highlightListAddHighlightIconContainer =
+ highlightListAddHighlightIconContainerFinder
+ .evaluate()
+ .first
+ .widget as Container;
+ bool highlightListAddHighlightIconContainerIsBoxDecoration =
+ checkError(
+ 148,
+ highlightListAddHighlightIconContainer.decoration,
+ isA(),
+ );
+ if (highlightListAddHighlightIconContainerIsBoxDecoration) {
+ final highlightListAddHighlightIconContainerDecoration =
+ highlightListAddHighlightIconContainer.decoration
+ as BoxDecoration;
+ checkError(
+ 149,
+ highlightListAddHighlightIconContainerDecoration.shape,
+ BoxShape.circle,
+ );
+ checkError(
+ 150,
+ highlightListAddHighlightIconContainerDecoration.border,
+ Border.all(color: Colors.black, width: 2),
+ );
+ }
+ }
+
+ final highlightListAddHighlightIconFinder = find.byKey(
+ const Key("highlight_list_add_highlight_icon"),
+ );
+ bool highlightListAddHighlightIconIsAvailable = checkError(
+ 151,
+ find.descendant(
+ of: highlightListAddHighlightIconContainerFinder,
+ matching: highlightListAddHighlightIconFinder,
+ ),
+ findsOneWidget,
+ );
+
+ if (highlightListAddHighlightIconIsAvailable) {
+ bool highlightListAddHighlightIconIsIcon = checkError(
+ 152,
+ highlightListAddHighlightIconFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (highlightListAddHighlightIconIsIcon) {
+ final highlightListAddHighlightIcon =
+ highlightListAddHighlightIconFinder
+ .evaluate()
+ .first
+ .widget as Icon;
+ checkError(
+ 153,
+ highlightListAddHighlightIcon.icon,
+ Icons.add,
+ );
+ checkError(
+ 154,
+ highlightListAddHighlightIcon.color,
+ Colors.white,
+ );
+ }
+ }
+ }
+ }
+
+ final highlightListAddHighlightTextSizedBoxFinder = find.byKey(
+ const Key("highlight_list_add_highlight_text_sized_box"),
+ );
+ bool highlightListAddHighlightTextSizedBoxIsAvailable = checkError(
+ 155,
+ find.descendant(
+ of: highlightListAddHighlightColumnFinder,
+ matching: highlightListAddHighlightTextSizedBoxFinder,
+ ),
+ findsOneWidget,
+ );
+
+ if (highlightListAddHighlightTextSizedBoxIsAvailable) {
+ bool highlightListAddHighlightTextSizedBoxIsSizedBox = checkError(
+ 156,
+ highlightListAddHighlightTextSizedBoxFinder
+ .evaluate()
+ .first
+ .widget,
+ isA(),
+ );
+ if (highlightListAddHighlightTextSizedBoxIsSizedBox) {
+ final highlightListAddHighlightTextSizedBox =
+ highlightListAddHighlightTextSizedBoxFinder
+ .evaluate()
+ .first
+ .widget as SizedBox;
+ checkError(
+ 157, highlightListAddHighlightTextSizedBox.width, 70);
+ }
+
+ final highlightListAddHighlightTextFinder = find.byKey(
+ const Key("highlight_list_add_highlight_text"),
+ );
+ bool highlightListAddHighlightTextIsAvailable = checkError(
+ 158,
+ find.descendant(
+ of: highlightListAddHighlightTextSizedBoxFinder,
+ matching: highlightListAddHighlightTextFinder,
+ ),
+ findsOneWidget,
+ );
+
+ if (highlightListAddHighlightTextIsAvailable) {
+ bool highlightListAddHighlightTextIsText = checkError(
+ 159,
+ highlightListAddHighlightTextFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (highlightListAddHighlightTextIsText) {
+ final highlightListAddHighlightText =
+ highlightListAddHighlightTextFinder
+ .evaluate()
+ .first
+ .widget as Text;
+ checkError(160, highlightListAddHighlightText.data, "New");
+ checkError(
+ 161,
+ highlightListAddHighlightText.overflow,
+ TextOverflow.ellipsis,
+ );
+ checkError(
+ 162,
+ highlightListAddHighlightText.textAlign,
+ TextAlign.center,
+ );
+ bool highlightListAddHighlightTextIsTextStyle = checkError(
+ 163,
+ highlightListAddHighlightText.style,
+ isA(),
+ );
+ if (highlightListAddHighlightTextIsTextStyle) {
+ final highlightListAddHighlightTextStyle =
+ highlightListAddHighlightText.style as TextStyle;
+ checkError(
+ 164,
+ highlightListAddHighlightTextStyle.color,
+ Colors.white,
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ });
+ testWidgets("Check if Highlight Item is rendered correctly",
+ (widgetTester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+ final img = stories[0]["img"];
+ final name = stories[0]["name"];
+ await widgetTester.pumpWidget(
+ MaterialApp(
+ home: HighlightItem(
+ img: img,
+ name: name,
+ ),
+ ),
+ );
+
+ final highlightItemPaddingFinder = find.byKey(
+ const Key("highlight_item_padding"),
+ );
+ bool highlightItemPaddingIsAvailable = checkError(
+ 165,
+ find.descendant(
+ of: find.byType(HighlightItem),
+ matching: highlightItemPaddingFinder,
+ ),
+ findsOneWidget,
+ );
+
+ if (highlightItemPaddingIsAvailable) {
+ bool highlightItemPaddingIsPadding = checkError(
+ 166,
+ highlightItemPaddingFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (highlightItemPaddingIsPadding) {
+ final highlightItemPadding =
+ highlightItemPaddingFinder.evaluate().first.widget as Padding;
+ checkError(
+ 167,
+ highlightItemPadding.padding,
+ const EdgeInsets.only(right: 10, bottom: 10),
+ );
+ }
+ final highlightItemColumnFinder = find.byKey(
+ const Key("highlight_item_column"),
+ );
+ bool highlightItemColumnIsAvailable = checkError(
+ 168,
+ find.descendant(
+ of: highlightItemPaddingFinder,
+ matching: highlightItemColumnFinder,
+ ),
+ findsOneWidget,
+ );
+
+ if (highlightItemColumnIsAvailable) {
+ bool highlightItemColumnIsColumn = checkError(
+ 169,
+ highlightItemColumnFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (highlightItemColumnIsColumn) {
+ final highlightItemColumn =
+ highlightItemColumnFinder.evaluate().first.widget as Column;
+ checkError(170, highlightItemColumn.children.length, 2);
+ }
+
+ final highlightItemContainerFinder = find.byKey(
+ const Key("highlight_item_container"),
+ );
+ bool highlightItemContainerIsAvailable = checkError(
+ 171,
+ find.descendant(
+ of: highlightItemColumnFinder,
+ matching: highlightItemContainerFinder,
+ ),
+ findsOneWidget,
+ );
+ if (highlightItemContainerIsAvailable) {
+ bool highlightItemContainerIsContainer = checkError(
+ 172,
+ highlightItemContainerFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (highlightItemContainerIsContainer) {
+ final highlightItemContainer = highlightItemContainerFinder
+ .evaluate()
+ .first
+ .widget as Container;
+ checkError(
+ 173,
+ highlightItemContainer.constraints!.widthConstraints(),
+ const BoxConstraints(minWidth: 68, maxWidth: 68),
+ );
+ checkError(
+ 174,
+ highlightItemContainer.constraints!.heightConstraints(),
+ const BoxConstraints(minHeight: 68, maxHeight: 68),
+ );
+ checkError(
+ 175,
+ highlightItemContainer.padding,
+ const EdgeInsets.all(3.0),
+ );
+ checkError(
+ 176,
+ highlightItemContainer.margin,
+ const EdgeInsets.only(bottom: 8),
+ );
+
+ bool highlightItemContainerDecorationIsBoxDecoration = checkError(
+ 177,
+ highlightItemContainer.decoration,
+ isA(),
+ );
+
+ if (highlightItemContainerDecorationIsBoxDecoration) {
+ final highlightItemContainerDecoration =
+ highlightItemContainer.decoration as BoxDecoration;
+ checkError(
+ 178, highlightItemContainerDecoration.shape, BoxShape.circle);
+ checkError(
+ 179,
+ highlightItemContainerDecoration.border,
+ Border.all(color: Colors.grey[800]!, width: 1),
+ );
+ }
+ }
+ }
+ final highlightItemImageContainerFinder = find.byKey(
+ const Key("highlight_item_image_container"),
+ );
+ bool highlightItemImageContainerIsAvailable = checkError(
+ 180,
+ find.descendant(
+ of: highlightItemContainerFinder,
+ matching: highlightItemImageContainerFinder,
+ ),
+ findsOneWidget,
+ );
+ if (highlightItemImageContainerIsAvailable) {
+ bool highlightItemImageContainerIsContainer = checkError(
+ 181,
+ highlightItemImageContainerFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (highlightItemImageContainerIsContainer) {
+ final highlightItemImageContainer =
+ highlightItemImageContainerFinder.evaluate().first.widget
+ as Container;
+ bool highlightItemImageContainerDecorationIsBoxDecoration =
+ checkError(182, highlightItemImageContainer.decoration,
+ isA());
+ if (highlightItemImageContainerDecorationIsBoxDecoration) {
+ final highlightItemImageContainerDecoration =
+ highlightItemImageContainer.decoration as BoxDecoration;
+ checkError(183, highlightItemImageContainerDecoration.shape,
+ BoxShape.circle);
+ checkError(
+ 184,
+ highlightItemImageContainerDecoration.border,
+ Border.all(color: Colors.black, width: 2),
+ );
+ bool highlightItemImageContainerDecorationImageIsDecorationImage =
+ checkError(
+ 185,
+ highlightItemImageContainerDecoration.image,
+ isA(),
+ );
+
+ if (highlightItemImageContainerDecorationImageIsDecorationImage) {
+ final highlightItemImageContainerDecorationImage =
+ highlightItemImageContainerDecoration.image
+ as DecorationImage;
+ checkError(186, highlightItemImageContainerDecorationImage.fit,
+ BoxFit.cover);
+ bool highlightItemImageContainerDecorationImageIsNetworkImage =
+ checkError(
+ 187,
+ highlightItemImageContainerDecorationImage.image,
+ isA(),
+ );
+
+ if (highlightItemImageContainerDecorationImageIsNetworkImage) {
+ final highlightItemImageContainerDecorationImageNetworkImage =
+ highlightItemImageContainerDecorationImage.image
+ as NetworkImage;
+ checkError(
+ 188,
+ highlightItemImageContainerDecorationImageNetworkImage.url,
+ img,
+ );
+ }
+ }
+ }
+ }
+ }
+
+ final highlightItemTextSizedBoxFinder = find.byKey(
+ const Key("highlight_item_text_sized_box"),
+ );
+ bool highlightItemTextSizedBoxIsAvailable = checkError(
+ 189,
+ find.descendant(
+ of: highlightItemColumnFinder,
+ matching: highlightItemTextSizedBoxFinder,
+ ),
+ findsOneWidget,
+ );
+
+ if (highlightItemTextSizedBoxIsAvailable) {
+ bool highlightItemTextSizedBoxIsSizedBox = checkError(
+ 190,
+ highlightItemTextSizedBoxFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (highlightItemTextSizedBoxIsSizedBox) {
+ final highlightItemTextSizedBox = highlightItemTextSizedBoxFinder
+ .evaluate()
+ .first
+ .widget as SizedBox;
+ checkError(191, highlightItemTextSizedBox.width, 70);
+ }
+ final highlightItemTextFinder = find.byKey(
+ const Key("highlight_item_text"),
+ );
+ bool highlightItemTextIsAvailable = checkError(
+ 192,
+ find.descendant(
+ of: highlightItemTextSizedBoxFinder,
+ matching: highlightItemTextFinder,
+ ),
+ findsOneWidget,
+ );
+ if (highlightItemTextIsAvailable) {
+ bool highlightItemTextIsText = checkError(
+ 193,
+ highlightItemTextFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (highlightItemTextIsText) {
+ final highlightItemText =
+ highlightItemTextFinder.evaluate().first.widget as Text;
+ checkError(
+ 194, highlightItemText.overflow, TextOverflow.ellipsis);
+ checkError(195, highlightItemText.textAlign, TextAlign.center);
+ bool highlightItemTextIsTextStyle = checkError(
+ 196,
+ highlightItemText.style,
+ isA(),
+ );
+ if (highlightItemTextIsTextStyle) {
+ final highlightItemTextStyle =
+ highlightItemText.style as TextStyle;
+ checkError(197, highlightItemTextStyle.color, Colors.white);
+ }
+ checkError(198, highlightItemText.data, name);
+ }
+ }
+ }
+ }
+ }
+ });
+ testWidgets("Check if Account tab is rendered correctly",
+ (widgetTester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+ const pageIndex = 0;
+
+ await mockNetworkImagesFor(
+ () => widgetTester.pumpWidget(
+ MaterialApp(
+ home: AccountTab(
+ pageIndex: pageIndex,
+ updateIndex: (updateIndex) {},
+ ),
+ ),
+ ),
+ );
+
+ final accountTabRowFinder = find.byKey(
+ const Key("account_tab_row"),
+ );
+ bool accountTabRowIsAvailable = checkError(
+ 199,
+ accountTabRowFinder,
+ findsOneWidget,
+ );
+ if (accountTabRowIsAvailable) {
+ bool accountTabRowIsRow = checkError(
+ 200,
+ accountTabRowFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (accountTabRowIsRow) {
+ final accountTabRow =
+ accountTabRowFinder.evaluate().first.widget as Row;
+ checkError(201, accountTabRow.children.length, tabs.length);
+ }
+
+ tabs.asMap().forEach((key, value) {
+ final accountTabDecoratedBoxFinder = find.byKey(
+ Key("account_tab_decorated_box_$key"),
+ );
+ bool accountTabDecoratedBoxIsAvailable = checkError(
+ 202,
+ find.descendant(
+ of: accountTabRowFinder,
+ matching: accountTabDecoratedBoxFinder,
+ ),
+ findsOneWidget,
+ );
+
+ if (accountTabDecoratedBoxIsAvailable) {
+ bool accountTabDecoratedBoxIsDecoratedBox = checkError(
+ 203,
+ accountTabDecoratedBoxFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (accountTabDecoratedBoxIsDecoratedBox) {
+ final accountTabDecoratedBox = accountTabDecoratedBoxFinder
+ .evaluate()
+ .first
+ .widget as DecoratedBox;
+ bool accountTabDecoratedBoxDecorationIsBoxDecoration = checkError(
+ 204,
+ accountTabDecoratedBox.decoration,
+ isA(),
+ );
+ if (accountTabDecoratedBoxDecorationIsBoxDecoration) {
+ final accountTabDecoratedBoxDecoration =
+ accountTabDecoratedBox.decoration as BoxDecoration;
+ bool accountTabDecoratedBoxDecorationBorderIsBorder = checkError(
+ 205,
+ accountTabDecoratedBoxDecoration.border,
+ isA(),
+ );
+ if (accountTabDecoratedBoxDecorationBorderIsBorder) {
+ final accountTabDecoratedBoxDecorationBorder =
+ accountTabDecoratedBoxDecoration.border as Border;
+ bool accountTabDecoratedBoxDecorationBorderBottomIsBorderSide =
+ checkError(
+ 206,
+ accountTabDecoratedBoxDecorationBorder.bottom,
+ isA(),
+ );
+ if (accountTabDecoratedBoxDecorationBorderBottomIsBorderSide) {
+ final accountTabDecoratedBoxDecorationBorderBottom =
+ accountTabDecoratedBoxDecorationBorder.bottom;
+ checkError(
+ 207,
+ accountTabDecoratedBoxDecorationBorderBottom.color,
+ (pageIndex == key) ? Colors.white : Colors.transparent,
+ );
+ checkError(
+ 208,
+ accountTabDecoratedBoxDecorationBorderBottom.width,
+ 2,
+ );
+ }
+ }
+ }
+ }
+ final accountTabElevatedButtonFinder = find.byKey(
+ Key("account_tab_elevated_button_$key"),
+ );
+ bool accountTabElevatedButtonIsAvailable = checkError(
+ 209,
+ find.descendant(
+ of: accountTabDecoratedBoxFinder,
+ matching: accountTabElevatedButtonFinder,
+ ),
+ findsOneWidget,
+ );
+ if (accountTabElevatedButtonIsAvailable) {
+ bool accountTabElevatedButtonIsElevatedButton = checkError(
+ 210,
+ accountTabElevatedButtonFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (accountTabElevatedButtonIsElevatedButton) {
+ final accountTabElevatedButton = accountTabElevatedButtonFinder
+ .evaluate()
+ .first
+ .widget as ElevatedButton;
+ bool accountTabElevatedButtonStyleIsButtonStyle = checkError(
+ 211,
+ accountTabElevatedButton.style,
+ isA(),
+ );
+ if (accountTabElevatedButtonStyleIsButtonStyle) {
+ final accountTabElevatedButtonStyle =
+ accountTabElevatedButton.style as ButtonStyle;
+ checkError(
+ 212,
+ accountTabElevatedButtonStyle.backgroundColor!
+ .resolve(states),
+ Colors.transparent,
+ );
+ checkError(
+ 213,
+ accountTabElevatedButtonStyle.elevation!.resolve(states),
+ 0,
+ );
+ }
+ }
+ final accountTabIconFinder = find.byKey(
+ Key("account_tab_icon_$key"),
+ );
+ bool accountTabIconIsAvailable = checkError(
+ 214,
+ find.descendant(
+ of: accountTabElevatedButtonFinder,
+ matching: accountTabIconFinder,
+ ),
+ findsOneWidget,
+ );
+ if (accountTabIconIsAvailable) {
+ bool accountTabIconIsIcon = checkError(
+ 215,
+ accountTabIconFinder.evaluate().first.widget,
+ isA(),
+ );
+ if (accountTabIconIsIcon) {
+ final accountTabIcon =
+ accountTabIconFinder.evaluate().first.widget as Icon;
+ checkError(216, accountTabIcon.color, Colors.white);
+ checkError(217, accountTabIcon.icon, tabs[key]['icon']);
+ }
+ }
+ }
+ }
+ });
+ }
+ });
+ testWidgets('Check if Account posts thumbnail is present',
+ (WidgetTester tester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+ const String imageUrl = "https://picsum.photos/250?image=9";
+ // mock screen size
+ tester.binding.window.physicalSizeTestValue = const Size(375, 812);
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ const MaterialApp(
+ home: PostThumbnail(imageUrl: imageUrl),
+ ),
+ ),
+ );
+
+ final postThumbnailContainerFinder = find.byKey(
+ const Key(imageUrl),
+ );
+ checkError(218, postThumbnailContainerFinder, findsOneWidget);
+
+ final postThumbnailContainer =
+ postThumbnailContainerFinder.evaluate().single.widget as Container;
+ checkError(219, postThumbnailContainer.decoration, isA());
+
+ final postThumbnailContainerDecoration =
+ postThumbnailContainer.decoration as BoxDecoration;
+ checkError(
+ 220,
+ postThumbnailContainerDecoration.image,
+ isA(),
+ );
+
+ final postThumbnailContainerDecorationImage =
+ postThumbnailContainerDecoration.image as DecorationImage;
+ checkError(
+ 221,
+ postThumbnailContainerDecorationImage.image,
+ isA(),
+ );
+ checkError(
+ 222,
+ postThumbnailContainerDecorationImage.fit,
+ BoxFit.cover,
+ );
+
+ final postThumbnailContainerDecorationImageNetworkImage =
+ postThumbnailContainerDecorationImage.image as NetworkImage;
+ checkError(
+ 223,
+ postThumbnailContainerDecorationImageNetworkImage.url,
+ imageUrl,
+ );
+ });
+
+ testWidgets('Check if Bottom Navbar is present', (WidgetTester tester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ MaterialApp(
+ home: AccountPage(
+ posts: posts,
+ stories: stories,
+ profileData: profileJson,
+ ),
+ ),
+ ),
+ );
+
+ int pageIndex = 4;
+
+ List bottomItems = [
+ pageIndex == 0
+ ? "assets/images/home_active_icon.svg"
+ : "assets/images/home_icon.svg",
+ pageIndex == 1
+ ? "assets/images/search_active_icon.svg"
+ : "assets/images/search_icon.svg",
+ pageIndex == 2
+ ? "assets/images/upload_active_icon.svg"
+ : "assets/images/upload_icon.svg",
+ pageIndex == 3
+ ? "assets/images/love_active_icon.svg"
+ : "assets/images/love_icon.svg",
+ pageIndex == 4
+ ? "assets/images/account_active_icon.svg"
+ : "assets/images/account_icon.svg",
+ ];
+
+ final bottomNavigationBarContainer =
+ find.byKey(const Key('bottom_navigation_bar_container'));
+ checkError(224, bottomNavigationBarContainer, findsOneWidget);
+
+ final bottomNavigationBarContainerFinder =
+ bottomNavigationBarContainer.evaluate().first.widget as Container;
+ checkError(
+ 225, bottomNavigationBarContainerFinder.constraints!.maxHeight, 55);
+ checkError(226, bottomNavigationBarContainerFinder.constraints!.maxWidth,
+ double.infinity);
+ checkError(227, bottomNavigationBarContainerFinder.color, Colors.black);
+ checkError(228, bottomNavigationBarContainerFinder.padding,
+ const EdgeInsets.only(left: 20, right: 20, bottom: 20, top: 15));
+
+ final bottomNavigationBarRowFinder =
+ find.byKey(const Key('bottom_navigation_bar_row'));
+ checkError(
+ 229,
+ find.descendant(
+ of: bottomNavigationBarContainer,
+ matching: bottomNavigationBarRowFinder),
+ findsOneWidget);
+
+ final bottomNavigationBarRow =
+ bottomNavigationBarRowFinder.evaluate().first.widget as Row;
+ checkError(230, bottomNavigationBarRow.mainAxisAlignment,
+ MainAxisAlignment.spaceBetween);
+ checkError(231, bottomNavigationBarRow.children, hasLength(5));
+
+ bottomItems.asMap().forEach((index, value) {
+ final bottomItem = bottomNavigationBarRow.children[index] as InkWell;
+ checkError(232, bottomItem.onTap, isA());
+ checkError(233, bottomItem.child, isA());
+
+ final bottomItemSvgPicture = bottomItem.child as SvgPicture;
+ checkError(234, bottomItemSvgPicture.pictureProvider.runtimeType,
+ ExactAssetPicture);
+ checkError(235, bottomItemSvgPicture.width, 27);
+ final bottomItemSvgPicturePictureProvider =
+ bottomItemSvgPicture.pictureProvider as ExactAssetPicture;
+ checkError(236, bottomItemSvgPicturePictureProvider.assetName,
+ bottomItems[index]);
+ });
+ });
+}
diff --git a/clone-instagram-login-Refactoring/test/calculator_test.dart b/clone-instagram-login-Refactoring/test/calculator_test.dart
new file mode 100644
index 0000000..b128e0d
--- /dev/null
+++ b/clone-instagram-login-Refactoring/test/calculator_test.dart
@@ -0,0 +1,39 @@
+import 'package:example_widget_testing/app/modules/calculator.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:network_image_mock/network_image_mock.dart';
+
+import 'test_library.dart';
+
+void main() {
+ testWidgets('Check if Calculator is functioning',
+ (WidgetTester tester) async {
+ FlutterError.onError = customFlutterErrorHandler;
+
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ const MaterialApp(
+ home: SimpleCalculator(),
+ ),
+ ),
+ );
+
+ const variableA = '2';
+ const variableB = '3';
+ const result = '5';
+ final variableAField = find.byKey(const Key('variableA'));
+ final variableBField = find.byKey(const Key('variableB'));
+ var resultTextFinder = find.byKey(const Key('result'));
+ checkByKeyFindOneWidget(resultTextFinder);
+
+ await tester.enterText(variableAField, variableA);
+ await tester.enterText(variableBField, variableB);
+ await tester.tap(find.byKey(const Key('addButton')));
+ await tester.pumpAndSettle();
+
+ var resultText = resultTextFinder.evaluate().first.widget as Text;
+ checkByKeyIsWidget(resultText, isA());
+ // expect(find.text(result), findsOneWidget);
+ checkWidgetProperty("data", resultTextFinder, resultText.data, result);
+ });
+}
diff --git a/clone-instagram-login-Refactoring/test/helper.dart b/clone-instagram-login-Refactoring/test/helper.dart
new file mode 100644
index 0000000..906fa9a
--- /dev/null
+++ b/clone-instagram-login-Refactoring/test/helper.dart
@@ -0,0 +1,27 @@
+import 'package:flutter/material.dart';
+
+void ignoreOverflowErrors(
+ FlutterErrorDetails details, {
+ bool forceReport = false,
+}) {
+ bool ifIsOverflowError = false;
+ bool isUnableToLoadAsset = false;
+
+ // Detect overflow error.
+ var exception = details.exception;
+ if (exception is FlutterError) {
+ ifIsOverflowError = !exception.diagnostics.any(
+ (e) => e.value.toString().startsWith("A RenderFlex overflowed by"),
+ );
+ isUnableToLoadAsset = !exception.diagnostics.any(
+ (e) => e.value.toString().startsWith("Unable to load asset"),
+ );
+ }
+
+ // Ignore if is overflow error.
+ if (ifIsOverflowError || isUnableToLoadAsset) {
+ debugPrint('Ignored Error');
+ } else {
+ FlutterError.dumpErrorToConsole(details, forceReport: forceReport);
+ }
+}
diff --git a/clone-instagram-login-Refactoring/test/search_page_test.dart b/clone-instagram-login-Refactoring/test/search_page_test.dart
new file mode 100644
index 0000000..7be9110
--- /dev/null
+++ b/clone-instagram-login-Refactoring/test/search_page_test.dart
@@ -0,0 +1,326 @@
+import 'package:example_widget_testing/app/modules/search/search_page.dart';
+import 'package:example_widget_testing/app/widgets/post_thumbnail.dart';
+import 'package:example_widget_testing/core/theme/colors.dart';
+import 'package:example_widget_testing/core/values/constant/search_json.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:network_image_mock/network_image_mock.dart';
+
+import 'helper.dart';
+
+void checkError(int index, dynamic expected, dynamic matcher) {
+ try {
+ expect(expected, matcher);
+ } catch (e) {
+ debugPrint('Searchpage Test-$index failed:');
+ debugPrint(e.toString());
+ }
+}
+
+void main() {
+ testWidgets('Check if Search page is present', (WidgetTester tester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ MaterialApp(
+ home: SearchPage(searchPosts: searchImages),
+ ),
+ ),
+ );
+
+ final searchPageListviewFinder = find.byKey(
+ const Key('search_page_listview'),
+ );
+ checkError(
+ 1,
+ searchPageListviewFinder,
+ findsOneWidget,
+ );
+ });
+
+ testWidgets('Check if search textfield is present',
+ (WidgetTester tester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ MaterialApp(
+ home: SearchPage(searchPosts: searchImages),
+ ),
+ ),
+ );
+
+ final searchPageListviewFinder = find.byKey(
+ const Key('search_page_listview'),
+ );
+
+ final searchPageTextfieldContainerFinder = find.byKey(
+ const Key('search_page_textfield_container'),
+ );
+ // mock screen size
+ tester.binding.window.physicalSizeTestValue = const Size(375, 812);
+ checkError(
+ 2,
+ find.descendant(
+ of: searchPageListviewFinder,
+ matching: searchPageTextfieldContainerFinder,
+ ),
+ findsOneWidget);
+ final searchPageTextfieldContainer = searchPageTextfieldContainerFinder
+ .evaluate()
+ .single
+ .widget as Container;
+
+ checkError(
+ 3,
+ searchPageTextfieldContainer.margin,
+ const EdgeInsets.only(
+ bottom: 15,
+ left: 15,
+ right: 15,
+ ),
+ );
+
+ checkError(4, searchPageTextfieldContainer.constraints!.maxHeight, 45.0);
+ checkError(
+ 5,
+ searchPageTextfieldContainer.decoration,
+ isA(),
+ );
+
+ final searchPageTextfieldContainerDecoration =
+ searchPageTextfieldContainer.decoration as BoxDecoration;
+ checkError(
+ 6,
+ searchPageTextfieldContainerDecoration.borderRadius,
+ const BorderRadius.all(Radius.circular(10)),
+ );
+ checkError(
+ 7,
+ searchPageTextfieldContainerDecoration.color,
+ const Color(0xff262626),
+ );
+
+ final searchPageTextfieldFinder = find.byKey(
+ const Key('search_page_textfield'),
+ );
+ checkError(
+ 8,
+ find.descendant(
+ of: searchPageListviewFinder,
+ matching: searchPageTextfieldFinder,
+ ),
+ findsOneWidget,
+ );
+
+ final searchPageTextfield =
+ searchPageTextfieldFinder.evaluate().single.widget as TextField;
+ checkError(9, searchPageTextfield.cursorColor, white.withOpacity(0.3));
+ checkError(10, searchPageTextfield.style, isA());
+
+ final searchPageTextfieldStyle = searchPageTextfield.style as TextStyle;
+ checkError(11, searchPageTextfieldStyle.color, white.withOpacity(0.3));
+
+ checkError(12, searchPageTextfield.decoration, isA());
+
+ final searchPageTextfieldDecoration =
+ searchPageTextfield.decoration as InputDecoration;
+ checkError(13, searchPageTextfieldDecoration.border, InputBorder.none);
+ checkError(14, searchPageTextfieldDecoration.prefixIcon, isA());
+
+ final searchPageTextfieldPrefixIcon =
+ searchPageTextfieldDecoration.prefixIcon as Icon;
+ checkError(15, searchPageTextfieldPrefixIcon.icon, Icons.search);
+ checkError(16, searchPageTextfieldPrefixIcon.color, white.withOpacity(0.3));
+
+ final searchPageWrapFinder = find.byKey(
+ const Key('search_page_wrap'),
+ );
+ checkError(
+ 17,
+ find.descendant(
+ of: searchPageListviewFinder,
+ matching: searchPageWrapFinder,
+ ),
+ findsOneWidget,
+ );
+
+ final searchPageWrap =
+ searchPageWrapFinder.evaluate().single.widget as Wrap;
+ checkError(18, searchPageWrap.spacing, 1);
+ checkError(19, searchPageWrap.runSpacing, 1);
+ checkError(20, searchPageWrap.children.length, searchImages.length);
+ });
+
+ testWidgets('Check if search posts is present', (WidgetTester tester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ MaterialApp(
+ home: SearchPage(searchPosts: searchImages),
+ ),
+ ),
+ );
+
+ final searchPageListviewFinder = find.byKey(
+ const Key('search_page_listview'),
+ );
+ final searchPageWrapFinder = find.byKey(
+ const Key('search_page_wrap'),
+ );
+ checkError(
+ 21,
+ find.descendant(
+ of: searchPageListviewFinder,
+ matching: searchPageWrapFinder,
+ ),
+ findsOneWidget,
+ );
+ checkError(
+ 22,
+ find.descendant(
+ of: searchPageWrapFinder,
+ matching: find.byType(Container),
+ ),
+ findsNWidgets(searchImages.length),
+ );
+ });
+
+ testWidgets('Check if search posts thumbnail is present',
+ (WidgetTester tester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+ const String imageUrl = "https://picsum.photos/250?image=9";
+ // mock screen size
+ tester.binding.window.physicalSizeTestValue = const Size(375, 812);
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ const MaterialApp(
+ home: PostThumbnail(imageUrl: imageUrl),
+ ),
+ ),
+ );
+
+ final postThumbnailContainerFinder = find.byKey(
+ const Key(imageUrl),
+ );
+ checkError(23, postThumbnailContainerFinder, findsOneWidget);
+
+ final postThumbnailContainer =
+ postThumbnailContainerFinder.evaluate().single.widget as Container;
+ checkError(24, postThumbnailContainer.decoration, isA());
+
+ final postThumbnailContainerDecoration =
+ postThumbnailContainer.decoration as BoxDecoration;
+ checkError(
+ 25,
+ postThumbnailContainerDecoration.image,
+ isA(),
+ );
+
+ final postThumbnailContainerDecorationImage =
+ postThumbnailContainerDecoration.image as DecorationImage;
+ checkError(
+ 26,
+ postThumbnailContainerDecorationImage.image,
+ isA(),
+ );
+ checkError(
+ 27,
+ postThumbnailContainerDecorationImage.fit,
+ BoxFit.cover,
+ );
+
+ final postThumbnailContainerDecorationImageNetworkImage =
+ postThumbnailContainerDecorationImage.image as NetworkImage;
+ checkError(
+ 28,
+ postThumbnailContainerDecorationImageNetworkImage.url,
+ imageUrl,
+ );
+ });
+
+ testWidgets('Check if Bottom Navbar is present', (WidgetTester tester) async {
+ FlutterError.onError = ignoreOverflowErrors;
+
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ MaterialApp(
+ home: SearchPage(searchPosts: searchImages),
+ ),
+ ),
+ );
+
+ int pageIndex = 1;
+
+ final bottomItem2Finder = find.byKey(
+ const Key('bottom_item_1'),
+ );
+ checkError(29, bottomItem2Finder, findsOneWidget);
+
+ await tester.ensureVisible(bottomItem2Finder);
+ await tester.pumpAndSettle();
+ await tester.tap(bottomItem2Finder);
+
+ List bottomItems = [
+ pageIndex == 0
+ ? "assets/images/home_active_icon.svg"
+ : "assets/images/home_icon.svg",
+ pageIndex == 1
+ ? "assets/images/search_active_icon.svg"
+ : "assets/images/search_icon.svg",
+ pageIndex == 2
+ ? "assets/images/upload_active_icon.svg"
+ : "assets/images/upload_icon.svg",
+ pageIndex == 3
+ ? "assets/images/love_active_icon.svg"
+ : "assets/images/love_icon.svg",
+ pageIndex == 4
+ ? "assets/images/account_active_icon.svg"
+ : "assets/images/account_icon.svg",
+ ];
+
+ final bottomNavigationBarContainer =
+ find.byKey(const Key('bottom_navigation_bar_container'));
+ checkError(188, bottomNavigationBarContainer, findsOneWidget);
+
+ final bottomNavigationBarContainerFinder =
+ bottomNavigationBarContainer.evaluate().first.widget as Container;
+ checkError(
+ 189, bottomNavigationBarContainerFinder.constraints!.maxHeight, 55);
+ checkError(190, bottomNavigationBarContainerFinder.constraints!.maxWidth,
+ double.infinity);
+ checkError(191, bottomNavigationBarContainerFinder.color, black);
+ checkError(192, bottomNavigationBarContainerFinder.padding,
+ const EdgeInsets.only(left: 20, right: 20, bottom: 20, top: 15));
+
+ final bottomNavigationBarRowFinder =
+ find.byKey(const Key('bottom_navigation_bar_row'));
+ checkError(
+ 193,
+ find.descendant(
+ of: bottomNavigationBarContainer,
+ matching: bottomNavigationBarRowFinder),
+ findsOneWidget);
+
+ final bottomNavigationBarRow =
+ bottomNavigationBarRowFinder.evaluate().first.widget as Row;
+ checkError(194, bottomNavigationBarRow.mainAxisAlignment,
+ MainAxisAlignment.spaceBetween);
+ checkError(195, bottomNavigationBarRow.children, hasLength(5));
+
+ bottomItems.asMap().forEach((index, value) {
+ final bottomItem = bottomNavigationBarRow.children[index] as InkWell;
+ checkError(196, bottomItem.onTap, isA());
+ checkError(197, bottomItem.child, isA());
+
+ final bottomItemSvgPicture = bottomItem.child as SvgPicture;
+ checkError(198, bottomItemSvgPicture.pictureProvider.runtimeType,
+ ExactAssetPicture);
+ checkError(199, bottomItemSvgPicture.width, 27);
+ final bottomItemSvgPicturePictureProvider =
+ bottomItemSvgPicture.pictureProvider as ExactAssetPicture;
+ checkError(200, bottomItemSvgPicturePictureProvider.assetName,
+ bottomItems[index]);
+ });
+ });
+}
diff --git a/clone-instagram-login-Refactoring/test/task_2_test.dart b/clone-instagram-login-Refactoring/test/task_2_test.dart
new file mode 100644
index 0000000..40fdbe4
--- /dev/null
+++ b/clone-instagram-login-Refactoring/test/task_2_test.dart
@@ -0,0 +1,358 @@
+import 'package:example_widget_testing/app/modules/login/login_page.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'test_library.dart';
+
+const List languages = [
+ 'English',
+ 'Arabic',
+ 'Italian',
+ 'French'
+];
+
+void main() {
+ final states = {};
+
+ testWidgets('Check if language dropdown is present', (tester) async {
+ FlutterError.onError = customFlutterErrorHandler;
+ await tester.pumpWidget(const MaterialApp(home: LoginPage()));
+ final dropdownButtonFinder = find.byType(DropdownButton);
+ final dropdownButton =
+ dropdownButtonFinder.evaluate().first.widget as DropdownButton;
+
+ checkByTypeFindOneWidget(dropdownButtonFinder);
+ checkWidgetProperty(
+ "dropdownColor",
+ dropdownButtonFinder,
+ dropdownButton.dropdownColor,
+ Colors.white,
+ );
+
+ checkWidgetProperty(
+ "color",
+ dropdownButtonFinder,
+ dropdownButton.style!.color,
+ Colors.black54,
+ );
+ checkWidgetProperty(
+ "elevation",
+ dropdownButtonFinder,
+ dropdownButton.elevation,
+ 10,
+ );
+ for (var language in languages) {
+ checkWidgetProperty(
+ "Text.data",
+ dropdownButtonFinder,
+ (dropdownButton.items!
+ .where((item) => item.value == language)
+ .first
+ .child as Text)
+ .data,
+ language,
+ );
+ }
+ for (var language in languages) {
+ checkWidgetProperty(
+ "fontSize",
+ dropdownButtonFinder,
+ (dropdownButton.items!
+ .where((item) => item.value == language)
+ .first
+ .child as Text)
+ .style!
+ .fontSize,
+ 16,
+ );
+ }
+ });
+
+ testWidgets('Check if username textbox is present', (tester) async {
+ FlutterError.onError = customFlutterErrorHandler;
+ tester.binding.window.physicalSizeTestValue = const Size(360, 640);
+ addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
+
+ await tester.pumpWidget(const MaterialApp(home: LoginPage()));
+ final usernameTextboxFinder = find.byKey(const Key('username_textfield'));
+
+ final usernameTextbox =
+ usernameTextboxFinder.evaluate().first.widget as TextField;
+ checkByKeyFindOneWidget(usernameTextboxFinder);
+ checkWidgetProperty(
+ "hintText",
+ usernameTextboxFinder,
+ usernameTextbox.decoration!.hintText,
+ 'Phone number , email or username',
+ );
+ checkWidgetProperty(
+ "fontSize",
+ usernameTextboxFinder,
+ usernameTextbox.style!.fontSize,
+ 15,
+ );
+ });
+
+ testWidgets('Check if password textbox is present', (tester) async {
+ FlutterError.onError = customFlutterErrorHandler;
+ tester.binding.window.physicalSizeTestValue = const Size(360, 640);
+ addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
+
+ await tester.pumpWidget(const MaterialApp(home: LoginPage()));
+
+ final passwordTextboxFinder = find.byKey(const Key('password_textfield'));
+ checkByKeyFindOneWidget(passwordTextboxFinder);
+
+ final passwordTextbox =
+ passwordTextboxFinder.evaluate().first.widget as TextField;
+ checkWidgetProperty(
+ "hintText",
+ passwordTextboxFinder,
+ passwordTextbox.decoration!.hintText,
+ 'Password',
+ );
+
+ await tester.enterText(passwordTextboxFinder, 'password');
+ checkWidgetProperty(
+ "obscureText",
+ passwordTextboxFinder,
+ passwordTextbox.obscureText,
+ true,
+ );
+ });
+
+ testWidgets('Check if login button is present', (tester) async {
+ FlutterError.onError = customFlutterErrorHandler;
+ await tester.pumpWidget(const MaterialApp(home: LoginPage()));
+
+ final loginButtonFinder = find.byKey(
+ const Key('login_button_elevated_button'),
+ );
+
+ final loginButton =
+ loginButtonFinder.evaluate().first.widget as ElevatedButton;
+ checkByKeyFindOneWidget(loginButtonFinder);
+ checkWidgetProperty(
+ "backgroundColor",
+ loginButtonFinder,
+ loginButton.style!.backgroundColor!.resolve(states),
+ const Color(0xff78c9ff),
+ );
+ });
+
+ testWidgets('Check Forgot Login Text', (tester) async {
+ FlutterError.onError = customFlutterErrorHandler;
+ await tester.pumpWidget(const MaterialApp(home: LoginPage()));
+
+ final forgotAccessFinder = find.byKey(const Key('forgot_access_text'));
+ checkByKeyFindOneWidget(forgotAccessFinder);
+
+ final forgotAccessText = forgotAccessFinder.evaluate().first.widget as Text;
+ checkWidgetProperty(
+ "Text.data",
+ forgotAccessFinder,
+ forgotAccessText.data,
+ 'Forgot your login details? ',
+ );
+ checkWidgetProperty(
+ "fontSize",
+ forgotAccessFinder,
+ forgotAccessText.style!.fontSize,
+ 13,
+ );
+ checkWidgetProperty(
+ "color",
+ forgotAccessFinder,
+ forgotAccessText.style!.color,
+ Colors.black,
+ );
+ checkWidgetProperty(
+ "fontWeight",
+ forgotAccessFinder,
+ forgotAccessText.style!.fontWeight,
+ FontWeight.normal,
+ );
+ });
+
+ testWidgets('Check if Get Help text is present', (tester) async {
+ FlutterError.onError = customFlutterErrorHandler;
+
+ await tester.pumpWidget(const MaterialApp(home: LoginPage()));
+
+ final getHelpFinder = find.byKey(const Key('get_help_text'));
+ checkByKeyFindOneWidget(getHelpFinder);
+
+ final getHelpText = getHelpFinder.evaluate().first.widget as Text;
+ checkWidgetProperty(
+ "Text.data",
+ getHelpFinder,
+ getHelpText.data,
+ 'Get help',
+ );
+ checkWidgetProperty(
+ "fontSize",
+ getHelpFinder,
+ getHelpText.style!.fontSize,
+ 13,
+ );
+ checkWidgetProperty(
+ "color",
+ getHelpFinder,
+ getHelpText.style!.color,
+ const Color(0xff002588),
+ );
+ checkWidgetProperty(
+ "fontWeight",
+ getHelpFinder,
+ getHelpText.style!.fontWeight,
+ FontWeight.bold,
+ );
+ });
+
+ testWidgets('Check if Facebook login is present', (tester) async {
+ FlutterError.onError = customFlutterErrorHandler;
+
+ await tester.pumpWidget(const MaterialApp(home: LoginPage()));
+
+ final facebookLoginFinder = find.byKey(const Key('facebook_login'));
+ checkByKeyFindOneWidget(facebookLoginFinder);
+
+ final facebookLogo = find.byKey(const Key('facebook_logo'));
+ checkByKeyFindOneWidget(facebookLogo);
+
+ final facebookTextFinder = find.byKey(const Key('facebook_login_text'));
+ checkByKeyFindOneWidget(facebookTextFinder);
+
+ final facebookText = facebookTextFinder.evaluate().first.widget as Text;
+ checkWidgetProperty(
+ "Text.data",
+ facebookTextFinder,
+ facebookText.data,
+ 'Login with facebook',
+ );
+ checkWidgetProperty(
+ "color",
+ facebookTextFinder,
+ facebookText.style!.color,
+ const Color(0xff1877f2),
+ );
+ checkWidgetProperty(
+ "fontWeight",
+ facebookTextFinder,
+ facebookText.style!.fontWeight,
+ FontWeight.w800,
+ );
+ });
+
+ testWidgets('Check if signup text is present', (tester) async {
+ FlutterError.onError = customFlutterErrorHandler;
+
+ await tester.pumpWidget(const MaterialApp(home: LoginPage()));
+
+ final signupSectionFinder = find.byKey(const Key('signup_section'));
+ checkByKeyFindOneWidget(signupSectionFinder);
+
+ final signupSection = signupSectionFinder.evaluate().first.widget as Row;
+ checkWidgetProperty(
+ "mainAxisAlignment",
+ signupSectionFinder,
+ signupSection.mainAxisAlignment,
+ MainAxisAlignment.center,
+ );
+
+ final signupText = signupSection.children[0] as Text;
+ checkWidgetProperty(
+ "Text.data",
+ signupSectionFinder.first,
+ signupText.data,
+ "Don't have an account? ",
+ );
+
+ checkWidgetProperty(
+ "fontSize",
+ signupSectionFinder,
+ signupText.style!.fontSize,
+ tester.binding.window.physicalSize.width * .040 / 3,
+ );
+
+ final signupButton = signupSection.children[1] as TextButton;
+ final signupButtonText = signupButton.child as Text;
+ checkWidgetProperty(
+ "Text.data",
+ signupSectionFinder,
+ signupButtonText.data,
+ 'Sign up',
+ );
+ checkWidgetProperty(
+ "color",
+ signupSectionFinder,
+ signupButtonText.style!.color,
+ const Color(0xff00258B),
+ );
+ checkWidgetProperty(
+ "fontWeight",
+ signupSectionFinder,
+ signupButtonText.style!.fontWeight,
+ FontWeight.bold,
+ );
+ checkWidgetProperty(
+ "fontSize",
+ signupSectionFinder,
+ signupButtonText.style!.fontSize,
+ tester.binding.window.physicalSize.width * .040 / 3,
+ );
+ });
+
+ // test if login button is disabled when username and password are empty
+ testWidgets(
+ 'Check if login button is disabled when username and password are empty',
+ (tester) async {
+ FlutterError.onError = customFlutterErrorHandler;
+ await tester.pumpWidget(const MaterialApp(home: LoginPage()));
+
+ final loginButtonFinder = find.byKey(
+ const Key('login_button_elevated_button'),
+ );
+
+ final loginButton =
+ loginButtonFinder.evaluate().first.widget as ElevatedButton;
+ checkByKeyFindOneWidget(loginButtonFinder);
+ checkWidgetProperty(
+ "backgroundColor",
+ loginButtonFinder,
+ loginButton.style!.backgroundColor!.resolve(states),
+ const Color(0xff78c9ff),
+ );
+ });
+
+ // test if login button is enabled when username and password are not empty
+ // testWidgets(
+ // "Check if login button is enabled when username and password are filled",
+ // (tester) async {
+ // FlutterError.onError = customFlutterErrorHandler;
+ // await tester.pumpWidget(const MaterialApp(home: LoginPage()));
+
+ // final loginButtonFinder = find.byKey(
+ // const Key('login_button_elevated_button'),
+ // );
+
+ // // find username textbox
+ // final usernameTextboxFinder = find.byKey(const Key('username_textfield'));
+ // // find password textbox
+ // final passwordTextboxFinder = find.byKey(const Key('password_textfield'));
+
+ // // enter username
+ // await tester.enterText(usernameTextboxFinder, 'username');
+ // // enter password
+ // await tester.enterText(passwordTextboxFinder, 'password');
+
+ // final loginButton =
+ // loginButtonFinder.evaluate().first.widget as ElevatedButton;
+ // checkByKeyFindOneWidget(loginButtonFinder);
+ // checkWidgetProperty(
+ // "backgroundColor",
+ // loginButtonFinder,
+ // loginButton.style!.backgroundColor!.resolve(states),
+ // const Color(0xff26A9FF),
+ // );
+ // });
+}
diff --git a/clone-instagram-login-Refactoring/test/task_3_test.dart b/clone-instagram-login-Refactoring/test/task_3_test.dart
new file mode 100644
index 0000000..8330c93
--- /dev/null
+++ b/clone-instagram-login-Refactoring/test/task_3_test.dart
@@ -0,0 +1,348 @@
+import 'package:example_widget_testing/app/modules/activity/activity_page.dart';
+import 'package:example_widget_testing/app/modules/home/components/story_item.dart';
+import 'package:example_widget_testing/app/modules/home/home_page.dart';
+import 'package:example_widget_testing/app/modules/login/login_page.dart';
+import 'package:example_widget_testing/core/values/constant/profile_json.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:network_image_mock/network_image_mock.dart';
+import 'package:example_widget_testing/core/values/constant/story_json.dart';
+import 'package:example_widget_testing/core/theme/colors.dart';
+import 'package:example_widget_testing/core/values/constant/post_json.dart';
+import 'test_library.dart';
+
+void main() {
+ testWidgets('Check if previous task 2 is finished',
+ (WidgetTester tester) async {
+ FlutterError.onError = unfinishedTaskErrorHandler;
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ const MaterialApp(
+ home: LoginPage(),
+ ),
+ ),
+ );
+ final loginPageFinder = find.byType(LoginPage);
+ checkByTypeFindOneWidget(loginPageFinder);
+ });
+
+ testWidgets('Check if home page is present', (WidgetTester tester) async {
+ FlutterError.onError = customFlutterErrorHandler;
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ MaterialApp(
+ home: HomePage(
+ posts: posts,
+ profileData: profileJson,
+ stories: stories,
+ ),
+ ),
+ ),
+ );
+ final homePageFinder = find.byType(HomePage);
+ checkByTypeFindOneWidget(homePageFinder);
+ });
+
+ testWidgets('Check if Home page Appbar is present',
+ (WidgetTester tester) async {
+ FlutterError.onError = customFlutterErrorHandler;
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ MaterialApp(
+ home: HomePage(
+ posts: posts, profileData: profileJson, stories: stories),
+ ),
+ ),
+ );
+
+ final appBarFinder = find.byKey(const Key('home_page_appbar'));
+ checkByKeyFindOneWidget(appBarFinder);
+
+ final appBar = appBarFinder.evaluate().first.widget as AppBar;
+ checkWidgetProperty(
+ "backgroundColor", appBar, appBar.backgroundColor, Colors.black);
+ checkByKeyIsWidget(appBar.leading, isA());
+
+ final appBarLeading = appBar.leading as Icon;
+ checkWidgetProperty("icon", appBar, appBarLeading.icon, Icons.camera_alt);
+ checkByKeyIsWidget(appBar.title, isA());
+
+ final appBarTitle = appBar.title as Center;
+ checkByKeyIsWidget(appBarTitle.child, isA());
+ checkByKeyIsWidget(appBar.actions, isA>());
+ // checkError(9, appBar.actions?.length, 1);
+
+ final appBarAction = appBar.actions?.first as Icon;
+ checkWidgetProperty("icon", appBar, appBarAction.icon, Icons.send);
+ });
+
+ testWidgets('Check if Story is present', (WidgetTester tester) async {
+ FlutterError.onError = customFlutterErrorHandler;
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ MaterialApp(
+ home: HomePage(
+ posts: posts,
+ profileData: profileJson,
+ stories: stories,
+ ),
+ ),
+ ),
+ );
+
+ final storyFinder = find.byKey(const Key('following_stories_row'));
+ checkByKeyFindOneWidget(storyFinder);
+
+ final story = storyFinder.evaluate().first.widget as Row;
+ checkByKeyIsWidget(story.children, isA>());
+ checkWidgetProperty(
+ "length", storyFinder, story.children.length, stories.length);
+ checkByKeyIsWidget(story.children[0], isA());
+
+ stories.asMap().forEach((index, value) {
+ final storyItem = story.children[index] as StoryItem;
+ checkWidgetProperty("name", storyFinder, storyItem.name, value['name']);
+ checkWidgetProperty("img", storyFinder, storyItem.img, value['img']);
+ });
+ });
+
+ testWidgets('Check if StoryItem rendered correctly',
+ (WidgetTester tester) async {
+ // Define test data
+ const String imageUrl = 'https://example.com/image.jpg';
+ const String name = 'John Doe';
+
+ FlutterError.onError = customFlutterErrorHandler;
+
+ await mockNetworkImagesFor(() => tester.pumpWidget(
+ const MaterialApp(home: StoryItem(img: imageUrl, name: name))));
+
+ // checkError(17, find.byType(Container), findsNWidgets(2));
+
+ final storyItemPaddingFinder = find.byKey(const Key('story_item_padding'));
+ checkByKeyFindOneWidget(storyItemPaddingFinder);
+
+ final storyItemPadding =
+ storyItemPaddingFinder.evaluate().first.widget as Padding;
+ checkWidgetProperty(
+ "padding",
+ storyItemPaddingFinder,
+ storyItemPadding.padding,
+ const EdgeInsets.only(right: 20, bottom: 10),
+ );
+
+ final storyItemColumnFinder = find.byKey(const Key('story_item_column'));
+ checkByKeyFindOneWidget(storyItemColumnFinder);
+ checkWidgetDescendantProperty(
+ storyItemPaddingFinder, storyItemColumnFinder);
+
+ final storyItemColumn =
+ storyItemColumnFinder.evaluate().first.widget as Column;
+ checkByKeyIsWidget(storyItemColumn.children, isA>());
+ // checkError(23, storyItemColumn.children.length, 2);
+
+ final storyItemContainerFinder = find.byKey(
+ const Key('story_item_container'),
+ );
+ checkWidgetDescendantProperty(
+ storyItemColumnFinder, storyItemContainerFinder);
+
+ final storyItemContainer =
+ storyItemContainerFinder.evaluate().first.widget as Container;
+
+ checkWidgetProperty(
+ "width",
+ storyItemContainerFinder,
+ storyItemContainer.constraints!.widthConstraints(),
+ const BoxConstraints(minWidth: 68, maxWidth: 68),
+ );
+
+ checkWidgetProperty(
+ "margin",
+ storyItemContainerFinder,
+ storyItemContainer.margin,
+ const EdgeInsets.only(bottom: 8),
+ );
+
+ checkWidgetProperty(
+ "height",
+ storyItemContainerFinder,
+ storyItemContainer.constraints!.heightConstraints(),
+ const BoxConstraints(minHeight: 68, maxHeight: 68),
+ );
+
+ checkByKeyIsWidget(storyItemContainer.decoration, isA());
+
+ final storyItemContainerDecoration =
+ storyItemContainer.decoration as BoxDecoration;
+ checkWidgetProperty(
+ "shape",
+ storyItemContainerFinder,
+ storyItemContainerDecoration.shape,
+ BoxShape.circle,
+ );
+
+ checkByKeyIsWidget(
+ storyItemContainerDecoration.gradient, isA());
+ final storyItemContainerGradient =
+ storyItemContainerDecoration.gradient as LinearGradient;
+ checkWidgetProperty(
+ "begin",
+ storyItemContainerFinder,
+ storyItemContainerGradient.begin,
+ Alignment.topCenter,
+ );
+ checkWidgetProperty(
+ 'end',
+ storyItemContainerFinder,
+ storyItemContainerGradient.end,
+ Alignment.bottomCenter,
+ );
+ checkWidgetProperty(
+ "colors",
+ storyItemContainerFinder,
+ storyItemContainerGradient.colors,
+ const [Color(0xFF9B2282), Color(0xFFEEA863)],
+ );
+
+ final storyItemImageContainerFinder = find.byKey(
+ const Key('story_item_image_container'),
+ );
+
+ checkWidgetDescendantProperty(
+ storyItemContainerFinder, storyItemImageContainerFinder);
+
+ final storyItemImageContainer =
+ storyItemImageContainerFinder.evaluate().first.widget as Container;
+
+ checkWidgetProperty(
+ "width",
+ storyItemImageContainerFinder,
+ storyItemImageContainer.constraints!.widthConstraints(),
+ const BoxConstraints(minWidth: 65, maxWidth: 65),
+ );
+
+ checkWidgetProperty(
+ "height",
+ storyItemImageContainerFinder,
+ storyItemImageContainer.constraints!.heightConstraints(),
+ const BoxConstraints(minHeight: 65, maxHeight: 65),
+ );
+
+ checkWidgetProperty(
+ "margin",
+ storyItemImageContainerFinder,
+ storyItemImageContainer.margin,
+ const EdgeInsets.all(3),
+ );
+
+ checkByKeyIsWidget(
+ storyItemImageContainer.decoration, isA());
+
+ final storyItemImageContainerDecoration =
+ storyItemImageContainer.decoration as BoxDecoration;
+ checkWidgetProperty(
+ "shape",
+ storyItemImageContainerFinder,
+ storyItemImageContainerDecoration.shape,
+ BoxShape.circle,
+ );
+ checkWidgetProperty(
+ "border",
+ storyItemImageContainerFinder,
+ storyItemImageContainerDecoration.border,
+ const Border.fromBorderSide(
+ BorderSide(
+ color: black,
+ width: 2,
+ style: BorderStyle.solid,
+ ),
+ ),
+ );
+
+ checkByKeyIsWidget(
+ storyItemImageContainerDecoration.image, isA());
+
+ final storyItemImageContainerDecorationImage =
+ (storyItemImageContainer.decoration as BoxDecoration).image
+ as DecorationImage;
+ checkByKeyIsWidget(
+ storyItemImageContainerDecorationImage.image, isA());
+
+ checkWidgetProperty(
+ "fit",
+ storyItemImageContainerFinder,
+ storyItemImageContainerDecorationImage.fit,
+ BoxFit.cover,
+ );
+
+ final storyItemUsernameSizeBoxFinder = find.byKey(
+ const Key('story_item_username_sizedbox'),
+ );
+
+ checkWidgetDescendantProperty(
+ storyItemColumnFinder, storyItemUsernameSizeBoxFinder);
+
+ final storyItemUsernameSizeBox =
+ storyItemUsernameSizeBoxFinder.evaluate().first.widget as SizedBox;
+ checkWidgetProperty(
+ "width",
+ storyItemUsernameSizeBoxFinder,
+ storyItemUsernameSizeBox.width,
+ 70,
+ );
+
+ final storyItemUsernameTextFinder = find.byKey(
+ const Key('story_item_username_text'),
+ );
+
+ checkWidgetDescendantProperty(
+ storyItemUsernameSizeBoxFinder, storyItemUsernameTextFinder);
+
+ final storyItemUsernameText =
+ storyItemUsernameTextFinder.evaluate().first.widget as Text;
+ checkWidgetProperty(
+ "data",
+ storyItemUsernameTextFinder,
+ storyItemUsernameText.data,
+ name,
+ );
+ checkWidgetProperty(
+ "overflow",
+ storyItemUsernameTextFinder,
+ storyItemUsernameText.overflow,
+ TextOverflow.ellipsis,
+ );
+ checkWidgetProperty(
+ "color",
+ storyItemUsernameTextFinder,
+ storyItemUsernameText.style!.color,
+ white,
+ );
+ });
+
+ testWidgets('Check if divider is present', (WidgetTester tester) async {
+ FlutterError.onError = customFlutterErrorHandler;
+
+ await tester.pumpWidget(
+ MaterialApp(
+ home: HomePage(
+ posts: posts,
+ profileData: profileJson,
+ stories: stories,
+ ),
+ ),
+ );
+
+ final dividerFinder = find.byKey(const Key('home_page_divider'));
+ checkByKeyFindOneWidget(dividerFinder);
+
+ final divider = dividerFinder.evaluate().first.widget as Divider;
+ checkWidgetProperty(
+ "color",
+ dividerFinder,
+ divider.color,
+ white.withOpacity(0.3),
+ );
+ });
+}
diff --git a/clone-instagram-login-Refactoring/test/task_4_test.dart b/clone-instagram-login-Refactoring/test/task_4_test.dart
new file mode 100644
index 0000000..defa422
--- /dev/null
+++ b/clone-instagram-login-Refactoring/test/task_4_test.dart
@@ -0,0 +1,1199 @@
+import 'package:example_widget_testing/app/modules/home/components/story_item.dart';
+import 'package:example_widget_testing/app/modules/home/home_page.dart';
+import 'package:example_widget_testing/app/modules/login/login_page.dart';
+import 'package:example_widget_testing/app/widgets/post_item.dart';
+import 'package:example_widget_testing/core/theme/colors.dart';
+import 'package:example_widget_testing/core/values/constant/post_json.dart';
+import 'package:example_widget_testing/core/values/constant/profile_json.dart';
+import 'package:example_widget_testing/core/values/constant/story_json.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:network_image_mock/network_image_mock.dart';
+
+import 'test_library.dart';
+
+void main() {
+ testWidgets('Check if Task 2 is finished', (WidgetTester tester) async {
+ FlutterError.onError = unfinishedTaskErrorHandler;
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ const MaterialApp(
+ home: LoginPage(),
+ ),
+ ),
+ );
+ final loginPageFinder = find.byType(LoginPage);
+ checkByTypeFindOneWidget(loginPageFinder);
+ });
+
+ testWidgets('Check if Task 3 is finished', (WidgetTester tester) async {
+ FlutterError.onError = unfinishedTaskErrorHandler;
+
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ MaterialApp(
+ home: HomePage(
+ posts: posts,
+ profileData: profileJson,
+ stories: stories,
+ ),
+ ),
+ ),
+ );
+ final homePageFinder = find.byType(HomePage);
+ checkByTypeFindOneWidget(homePageFinder);
+
+ final appBarFinder = find.byKey(const Key('home_page_appbar'));
+ checkByKeyFindOneWidget(appBarFinder);
+
+ final appBar = appBarFinder.evaluate().first.widget as AppBar;
+ checkWidgetProperty(
+ "backgroundColor", appBar, appBar.backgroundColor, Colors.black);
+ checkByKeyIsWidget(appBar.leading, isA());
+
+ final appBarLeading = appBar.leading as Icon;
+ checkWidgetProperty("icon", appBar, appBarLeading.icon, Icons.camera_alt);
+ checkByKeyIsWidget(appBar.title, isA());
+
+ final appBarTitle = appBar.title as Center;
+ checkByKeyIsWidget(appBarTitle.child, isA());
+ checkByKeyIsWidget(appBar.actions, isA>());
+ // checkError(9, appBar.actions?.length, 1);
+
+ final appBarAction = appBar.actions?.first as Icon;
+ checkWidgetProperty("icon", appBar, appBarAction.icon, Icons.send);
+
+ final storyFinder = find.byKey(const Key('following_stories_row'));
+ checkByKeyFindOneWidget(storyFinder);
+
+ final story = storyFinder.evaluate().first.widget as Row;
+ checkByKeyIsWidget(story.children, isA>());
+ checkWidgetProperty(
+ "length", storyFinder, story.children.length, stories.length);
+ checkByKeyIsWidget(story.children[0], isA());
+
+ stories.asMap().forEach((index, value) {
+ final storyItem = story.children[index] as StoryItem;
+ checkWidgetProperty("name", storyFinder, storyItem.name, value['name']);
+ checkWidgetProperty("img", storyFinder, storyItem.img, value['img']);
+ });
+
+ const String imageUrl = 'https://example.com/image.jpg';
+ const String name = 'John Doe';
+
+ FlutterError.onError = customFlutterErrorHandler;
+
+ await mockNetworkImagesFor(() => tester.pumpWidget(
+ const MaterialApp(home: StoryItem(img: imageUrl, name: name))));
+
+ // checkError(17, find.byType(Container), findsNWidgets(2));
+
+ final storyItemPaddingFinder = find.byKey(const Key('story_item_padding'));
+ checkByKeyFindOneWidget(storyItemPaddingFinder);
+
+ final storyItemPadding =
+ storyItemPaddingFinder.evaluate().first.widget as Padding;
+ checkWidgetProperty(
+ "padding",
+ storyItemPaddingFinder,
+ storyItemPadding.padding,
+ const EdgeInsets.only(right: 20, bottom: 10),
+ );
+
+ final storyItemColumnFinder = find.byKey(const Key('story_item_column'));
+ checkByKeyFindOneWidget(storyItemColumnFinder);
+ checkWidgetDescendantProperty(
+ storyItemPaddingFinder, storyItemColumnFinder);
+
+ final storyItemColumn =
+ storyItemColumnFinder.evaluate().first.widget as Column;
+ checkByKeyIsWidget(storyItemColumn.children, isA>());
+ // checkError(23, storyItemColumn.children.length, 2);
+
+ final storyItemContainerFinder = find.byKey(
+ const Key('story_item_container'),
+ );
+ checkWidgetDescendantProperty(
+ storyItemColumnFinder, storyItemContainerFinder);
+
+ final storyItemContainer =
+ storyItemContainerFinder.evaluate().first.widget as Container;
+
+ checkWidgetProperty(
+ "width",
+ storyItemContainerFinder,
+ storyItemContainer.constraints!.widthConstraints(),
+ const BoxConstraints(minWidth: 68, maxWidth: 68),
+ );
+
+ checkWidgetProperty(
+ "margin",
+ storyItemContainerFinder,
+ storyItemContainer.margin,
+ const EdgeInsets.only(bottom: 8),
+ );
+
+ checkWidgetProperty(
+ "height",
+ storyItemContainerFinder,
+ storyItemContainer.constraints!.heightConstraints(),
+ const BoxConstraints(minHeight: 68, maxHeight: 68),
+ );
+
+ checkByKeyIsWidget(storyItemContainer.decoration, isA());
+
+ final storyItemContainerDecoration =
+ storyItemContainer.decoration as BoxDecoration;
+ checkWidgetProperty(
+ "shape",
+ storyItemContainerFinder,
+ storyItemContainerDecoration.shape,
+ BoxShape.circle,
+ );
+
+ checkByKeyIsWidget(
+ storyItemContainerDecoration.gradient, isA());
+ final storyItemContainerGradient =
+ storyItemContainerDecoration.gradient as LinearGradient;
+ checkWidgetProperty(
+ "begin",
+ storyItemContainerFinder,
+ storyItemContainerGradient.begin,
+ Alignment.topCenter,
+ );
+ checkWidgetProperty(
+ 'end',
+ storyItemContainerFinder,
+ storyItemContainerGradient.end,
+ Alignment.bottomCenter,
+ );
+ checkWidgetProperty(
+ "colors",
+ storyItemContainerFinder,
+ storyItemContainerGradient.colors,
+ const [Color(0xFF9B2282), Color(0xFFEEA863)],
+ );
+
+ final storyItemImageContainerFinder = find.byKey(
+ const Key('story_item_image_container'),
+ );
+
+ checkWidgetDescendantProperty(
+ storyItemContainerFinder, storyItemImageContainerFinder);
+
+ final storyItemImageContainer =
+ storyItemImageContainerFinder.evaluate().first.widget as Container;
+
+ checkWidgetProperty(
+ "width",
+ storyItemImageContainerFinder,
+ storyItemImageContainer.constraints!.widthConstraints(),
+ const BoxConstraints(minWidth: 65, maxWidth: 65),
+ );
+
+ checkWidgetProperty(
+ "height",
+ storyItemImageContainerFinder,
+ storyItemImageContainer.constraints!.heightConstraints(),
+ const BoxConstraints(minHeight: 65, maxHeight: 65),
+ );
+
+ checkWidgetProperty(
+ "margin",
+ storyItemImageContainerFinder,
+ storyItemImageContainer.margin,
+ const EdgeInsets.all(3),
+ );
+
+ checkByKeyIsWidget(
+ storyItemImageContainer.decoration, isA());
+
+ final storyItemImageContainerDecoration =
+ storyItemImageContainer.decoration as BoxDecoration;
+ checkWidgetProperty(
+ "shape",
+ storyItemImageContainerFinder,
+ storyItemImageContainerDecoration.shape,
+ BoxShape.circle,
+ );
+ checkWidgetProperty(
+ "border",
+ storyItemImageContainerFinder,
+ storyItemImageContainerDecoration.border,
+ const Border.fromBorderSide(
+ BorderSide(
+ color: black,
+ width: 2,
+ style: BorderStyle.solid,
+ ),
+ ),
+ );
+
+ checkByKeyIsWidget(
+ storyItemImageContainerDecoration.image, isA());
+
+ final storyItemImageContainerDecorationImage =
+ (storyItemImageContainer.decoration as BoxDecoration).image
+ as DecorationImage;
+ checkByKeyIsWidget(
+ storyItemImageContainerDecorationImage.image, isA());
+
+ checkWidgetProperty(
+ "fit",
+ storyItemImageContainerFinder,
+ storyItemImageContainerDecorationImage.fit,
+ BoxFit.cover,
+ );
+
+ final storyItemUsernameSizeBoxFinder = find.byKey(
+ const Key('story_item_username_sizedbox'),
+ );
+
+ checkWidgetDescendantProperty(
+ storyItemColumnFinder, storyItemUsernameSizeBoxFinder);
+
+ final storyItemUsernameSizeBox =
+ storyItemUsernameSizeBoxFinder.evaluate().first.widget as SizedBox;
+ checkWidgetProperty(
+ "width",
+ storyItemUsernameSizeBoxFinder,
+ storyItemUsernameSizeBox.width,
+ 70,
+ );
+
+ final storyItemUsernameTextFinder = find.byKey(
+ const Key('story_item_username_text'),
+ );
+
+ checkWidgetDescendantProperty(
+ storyItemUsernameSizeBoxFinder, storyItemUsernameTextFinder);
+
+ final storyItemUsernameText =
+ storyItemUsernameTextFinder.evaluate().first.widget as Text;
+ checkWidgetProperty(
+ "data",
+ storyItemUsernameTextFinder,
+ storyItemUsernameText.data,
+ name,
+ );
+ checkWidgetProperty(
+ "overflow",
+ storyItemUsernameTextFinder,
+ storyItemUsernameText.overflow,
+ TextOverflow.ellipsis,
+ );
+ checkWidgetProperty(
+ "color",
+ storyItemUsernameTextFinder,
+ storyItemUsernameText.style!.color,
+ white,
+ );
+
+ await tester.pumpWidget(
+ MaterialApp(
+ home: HomePage(
+ posts: posts,
+ profileData: profileJson,
+ stories: stories,
+ ),
+ ),
+ );
+
+ final dividerFinder = find.byKey(const Key('home_page_divider'));
+ checkByKeyFindOneWidget(dividerFinder);
+
+ final divider = dividerFinder.evaluate().first.widget as Divider;
+ checkWidgetProperty(
+ "color",
+ dividerFinder,
+ divider.color,
+ white.withOpacity(0.3),
+ );
+ });
+
+ testWidgets('Check if Posts Column is present', (WidgetTester tester) async {
+ FlutterError.onError = customFlutterErrorHandler;
+
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ MaterialApp(
+ home: HomePage(
+ posts: posts,
+ profileData: profileJson,
+ stories: stories,
+ ),
+ ),
+ ),
+ );
+
+ final homePageColumnFinder = find.byKey(const Key('home_page_column'));
+ final postsColumnFinder = find.byKey(const Key('posts_column'));
+ checkWidgetDescendantProperty(homePageColumnFinder, postsColumnFinder);
+ checkByKeyFindOneWidget(postsColumnFinder);
+
+ final postsColumn = postsColumnFinder.evaluate().first.widget as Column;
+ checkError(53, postsColumn.children.length, posts.length);
+ });
+
+ testWidgets(
+ 'Check if PostItem rendered correctly',
+ (WidgetTester tester) async {
+ FlutterError.onError = customFlutterErrorHandler;
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ MaterialApp(
+ home: PostItem(
+ postImg: posts[0]['postImg'],
+ profileImg: posts[0]['profileImg'],
+ name: posts[0]['name'],
+ caption: posts[0]['caption'],
+ isLoved: posts[0]['isLoved'],
+ viewCount: posts[0]['commentCount'],
+ likedBy: posts[0]['likedBy'],
+ dayAgo: posts[0]['timeAgo'],
+ userPhoto: profile,
+ onPressed: () {},
+ ),
+ ),
+ ),
+ );
+
+ final postItemPaddingFinder = find.byKey(const Key('post_item_padding'));
+ checkByKeyFindOneWidget(postItemPaddingFinder);
+
+ final postItemPadding =
+ postItemPaddingFinder.evaluate().first.widget as Padding;
+ checkWidgetProperty(
+ "padding",
+ postItemPaddingFinder,
+ postItemPadding.padding,
+ const EdgeInsets.only(bottom: 10),
+ );
+
+ final postItemColumnFinder = find.byKey(const Key('post_item_column'));
+ checkWidgetDescendantProperty(
+ postItemPaddingFinder, postItemColumnFinder);
+
+ final postItemColumn =
+ postItemColumnFinder.evaluate().first.widget as Column;
+ checkWidgetProperty(
+ "crossAxisAlignment",
+ postItemColumnFinder,
+ postItemColumn.crossAxisAlignment,
+ CrossAxisAlignment.start,
+ );
+ // checkError(58, postItemColumn.children.length, 8);
+
+ final postItemUserInfoContainerFinder = find.byKey(
+ const Key('post_item_user_info_container'),
+ );
+ checkWidgetDescendantProperty(
+ postItemColumnFinder, postItemUserInfoContainerFinder);
+
+ final postItemUserInfoContainer =
+ postItemUserInfoContainerFinder.evaluate().first.widget as Container;
+ checkWidgetProperty(
+ "padding",
+ postItemUserInfoContainerFinder,
+ postItemUserInfoContainer.padding,
+ const EdgeInsets.symmetric(vertical: 10, horizontal: 15),
+ );
+
+ checkWidgetProperty(
+ "margin",
+ postItemUserInfoContainerFinder,
+ postItemUserInfoContainer.margin,
+ const EdgeInsets.only(bottom: 12),
+ );
+
+ final postItemUserInfoRowFinder = find.byKey(
+ const Key('post_item_user_info_row'),
+ );
+ checkWidgetDescendantProperty(
+ postItemUserInfoContainerFinder, postItemUserInfoRowFinder);
+
+ final postItemUserInfoRow =
+ postItemUserInfoRowFinder.evaluate().first.widget as Row;
+ checkWidgetProperty(
+ "mainAxisAlignment",
+ postItemUserInfoRowFinder,
+ postItemUserInfoRow.mainAxisAlignment,
+ MainAxisAlignment.spaceBetween,
+ );
+ // checkError(64, postItemUserInfoRow.children.length, 3);
+
+ final postItemUserImgContainerFinder = find.byKey(
+ const Key('post_item_user_profile_img_container'),
+ );
+ checkWidgetDescendantProperty(
+ postItemUserInfoRowFinder, postItemUserImgContainerFinder);
+
+ final postItemUserImgContainer =
+ postItemUserImgContainerFinder.evaluate().first.widget as Container;
+ checkWidgetProperty(
+ "width",
+ postItemUserImgContainerFinder,
+ postItemUserImgContainer.constraints!.maxWidth,
+ 40,
+ );
+ checkWidgetProperty(
+ "height",
+ postItemUserImgContainerFinder,
+ postItemUserImgContainer.constraints!.maxHeight,
+ 40,
+ );
+ checkWidgetProperty(
+ "margin",
+ postItemUserImgContainerFinder,
+ postItemUserImgContainer.margin,
+ const EdgeInsets.only(right: 15),
+ );
+ checkByKeyIsWidget(
+ postItemUserImgContainer.decoration, isA());
+
+ final postItemUserImgContainerDecoration =
+ postItemUserImgContainer.decoration as BoxDecoration;
+ checkWidgetProperty(
+ "shape",
+ postItemUserImgContainerFinder,
+ postItemUserImgContainerDecoration.shape,
+ BoxShape.circle,
+ );
+ checkByKeyIsWidget(
+ postItemUserImgContainerDecoration.image,
+ isA(),
+ );
+
+ final postItemUserImgContainerDecorationImage =
+ postItemUserImgContainerDecoration.image as DecorationImage;
+ checkByKeyIsWidget(
+ postItemUserImgContainerDecorationImage.image, isA());
+ checkWidgetProperty(
+ "fit",
+ postItemUserImgContainerFinder,
+ postItemUserImgContainerDecorationImage.fit,
+ BoxFit.cover,
+ );
+
+ final postItemUserImgContainerDecorationImageNetworkImage =
+ postItemUserImgContainerDecorationImage.image as NetworkImage;
+ checkWidgetProperty(
+ "ImageNetworkImage.url",
+ postItemUserImgContainerFinder,
+ postItemUserImgContainerDecorationImageNetworkImage.url,
+ posts[0]['profileImg'],
+ );
+
+ final postItemUserNameExpendedFinder = find.byKey(
+ const Key('post_item_user_name_expanded'),
+ );
+ checkWidgetDescendantProperty(
+ postItemUserInfoRowFinder, postItemUserNameExpendedFinder);
+
+ final postItemUserNameTextFinder = find.byKey(
+ const Key('post_item_user_name_text'),
+ );
+ checkWidgetDescendantProperty(
+ postItemUserNameExpendedFinder, postItemUserNameTextFinder);
+
+ final postItemUserNameText =
+ postItemUserNameTextFinder.evaluate().first.widget as Text;
+ checkWidgetProperty(
+ "data",
+ postItemUserNameTextFinder,
+ postItemUserNameText.data,
+ posts[0]['name'],
+ );
+ checkByKeyIsWidget(postItemUserNameText.style, isA());
+
+ final postItemUserNameTextStyle = postItemUserNameText.style as TextStyle;
+ checkWidgetProperty(
+ "color",
+ postItemUserNameTextFinder,
+ postItemUserNameTextStyle.color,
+ Colors.white,
+ );
+ checkWidgetProperty(
+ "fontWeight",
+ postItemUserNameTextFinder,
+ postItemUserNameTextStyle.fontWeight,
+ FontWeight.w500,
+ );
+ checkWidgetProperty(
+ "fontSize",
+ postItemUserNameTextFinder,
+ postItemUserNameTextStyle.fontSize,
+ 15,
+ );
+
+ final postItemUserMoreIconFinder = find.byKey(
+ const Key('post_item_user_more_icon'),
+ );
+ checkWidgetDescendantProperty(
+ postItemUserInfoRowFinder, postItemUserMoreIconFinder);
+
+ final postItemUserMoreIcon =
+ postItemUserMoreIconFinder.evaluate().first.widget as Icon;
+ checkWidgetProperty(
+ "icon",
+ postItemUserMoreIconFinder,
+ postItemUserMoreIcon.icon,
+ Icons.more_horiz,
+ );
+ checkWidgetProperty(
+ "color",
+ postItemUserMoreIconFinder,
+ postItemUserMoreIcon.color,
+ Colors.white,
+ );
+
+ final postItemImageContainerFinder = find.byKey(
+ const Key('post_item_image_container'),
+ );
+ checkWidgetDescendantProperty(
+ postItemColumnFinder, postItemImageContainerFinder);
+
+ final postItemImageContainer =
+ postItemImageContainerFinder.evaluate().first.widget as Container;
+ checkWidgetProperty(
+ "height",
+ postItemImageContainerFinder,
+ postItemImageContainer.constraints!.maxHeight,
+ 400,
+ );
+ checkWidgetProperty(
+ "margin",
+ postItemImageContainerFinder,
+ postItemImageContainer.margin,
+ const EdgeInsets.only(bottom: 10),
+ );
+ checkByKeyIsWidget(
+ postItemImageContainer.decoration, isA());
+
+ final postItemImageContainerDecoration =
+ postItemImageContainer.decoration as BoxDecoration;
+ checkByKeyIsWidget(
+ postItemImageContainerDecoration.image, isA());
+
+ final postItemImageContainerDecorationImage =
+ postItemImageContainerDecoration.image as DecorationImage;
+ checkByKeyIsWidget(
+ postItemImageContainerDecorationImage.image, isA());
+ checkWidgetProperty(
+ "fit",
+ postItemImageContainerFinder,
+ postItemImageContainerDecorationImage.fit,
+ BoxFit.cover,
+ );
+
+ final postItemImageContainerDecorationImageNetworkImage =
+ postItemImageContainerDecorationImage.image as NetworkImage;
+ checkWidgetProperty(
+ "ImageNetworkImage.url",
+ postItemImageContainerFinder,
+ postItemImageContainerDecorationImageNetworkImage.url,
+ posts[0]['postImg'],
+ );
+
+ final postItemActionContainerFinder =
+ find.byKey(const Key('post_item_actions_container'));
+ checkWidgetDescendantProperty(
+ postItemColumnFinder, postItemActionContainerFinder);
+
+ final postItemActionContainer =
+ postItemActionContainerFinder.evaluate().first.widget as Container;
+ checkWidgetProperty(
+ "padding",
+ postItemActionContainerFinder,
+ postItemActionContainer.padding,
+ const EdgeInsets.fromLTRB(15, 3, 15, 0),
+ );
+ checkWidgetProperty(
+ "margin",
+ postItemActionContainerFinder,
+ postItemActionContainer.margin,
+ const EdgeInsets.only(bottom: 12),
+ );
+
+ final postItemActionRowFinder = find.byKey(
+ const Key('post_item_actions_row'),
+ );
+ checkWidgetDescendantProperty(
+ postItemActionContainerFinder,
+ postItemActionRowFinder,
+ );
+
+ final postItemActionRow =
+ postItemActionRowFinder.evaluate().first.widget as Row;
+ checkWidgetProperty(
+ "mainAxisAlignment",
+ postItemActionRowFinder,
+ postItemActionRow.mainAxisAlignment,
+ MainAxisAlignment.spaceBetween,
+ );
+ // checkError(98, postItemActionRow.children.length, 2);
+
+ final postItemActionsLeftRowFinder = find.byKey(
+ const Key('post_item_actions_left_row'),
+ );
+ checkWidgetDescendantProperty(
+ postItemActionRowFinder, postItemActionsLeftRowFinder);
+
+ // final postItemActionsLeftRow =
+ // postItemActionsLeftRowFinder.evaluate().first.widget as Row;
+ // checkError(100, postItemActionsLeftRow.children.length, 5);
+
+ final postItemActionsLoveIconFinder = find.byKey(
+ const Key('post_item_actions_love_icon'),
+ );
+ checkWidgetDescendantProperty(
+ postItemActionsLeftRowFinder, postItemActionsLoveIconFinder);
+
+ final postItemActionsLoveIcon =
+ postItemActionsLoveIconFinder.evaluate().first.widget as SvgPicture;
+ checkByKeyIsWidget(postItemActionsLoveIcon, isA());
+ checkWidgetProperty(
+ "width",
+ postItemActionsLoveIconFinder,
+ postItemActionsLoveIcon.width,
+ 27,
+ );
+ checkWidgetProperty(
+ "pictureProvider.runtimeType",
+ postItemActionsLoveIconFinder,
+ postItemActionsLoveIcon.pictureProvider.runtimeType,
+ ExactAssetPicture,
+ );
+
+ final postItemActionsLoveIconPictureProvider =
+ postItemActionsLoveIcon.pictureProvider as ExactAssetPicture;
+ checkWidgetProperty(
+ "assetName",
+ postItemActionsLoveIconFinder,
+ postItemActionsLoveIconPictureProvider.assetName,
+ posts[0]['isLoved']
+ ? 'assets/images/loved_icon.svg'
+ : 'assets/images/love_icon.svg',
+ );
+ final postItemActionsLeftRowSizeBox1Finder = find.byKey(
+ const Key('post_item_actions_left_row_sized_box_1'),
+ );
+ checkWidgetDescendantProperty(
+ postItemActionsLeftRowFinder, postItemActionsLeftRowSizeBox1Finder);
+
+ final postItemActionsLeftRowSizeBox1 =
+ postItemActionsLeftRowSizeBox1Finder.evaluate().first.widget
+ as SizedBox;
+ checkWidgetProperty(
+ "width",
+ postItemActionsLeftRowSizeBox1Finder,
+ postItemActionsLeftRowSizeBox1.width,
+ 20,
+ );
+
+ final postItemActionsCommentIconFinder = find.byKey(
+ const Key('post_item_actions_comment_icon'),
+ );
+ checkWidgetDescendantProperty(
+ postItemActionsLeftRowFinder, postItemActionsCommentIconFinder);
+
+ final postItemActionsCommentIcon = postItemActionsCommentIconFinder
+ .evaluate()
+ .first
+ .widget as SvgPicture;
+ checkByKeyIsWidget(postItemActionsCommentIcon, isA());
+ checkWidgetProperty(
+ "width",
+ postItemActionsCommentIconFinder,
+ postItemActionsCommentIcon.width,
+ 27,
+ );
+ checkWidgetProperty(
+ "pictureProvider.runtimeType",
+ postItemActionsCommentIconFinder,
+ postItemActionsCommentIcon.pictureProvider.runtimeType,
+ ExactAssetPicture,
+ );
+
+ final postItemActionsCommentIconPictureProvider =
+ postItemActionsCommentIcon.pictureProvider as ExactAssetPicture;
+ checkWidgetProperty(
+ "assetName",
+ postItemActionsCommentIconFinder,
+ postItemActionsCommentIconPictureProvider.assetName,
+ "assets/images/comment_icon.svg",
+ );
+
+ final postItemActionsLeftRowSizeBox2Finder = find.byKey(
+ const Key('post_item_actions_left_row_sized_box_2'),
+ );
+ checkWidgetDescendantProperty(
+ postItemActionsLeftRowFinder, postItemActionsLeftRowSizeBox2Finder);
+
+ final postItemActionsLeftRowSizeBox2 =
+ postItemActionsLeftRowSizeBox2Finder.evaluate().first.widget
+ as SizedBox;
+ checkWidgetProperty(
+ "width",
+ postItemActionsLeftRowSizeBox2Finder,
+ postItemActionsLeftRowSizeBox2.width,
+ 20,
+ );
+
+ final postItemActionsMessageIconFinder = find.byKey(
+ const Key('post_item_actions_message_icon'),
+ );
+ checkWidgetDescendantProperty(
+ postItemActionsLeftRowFinder, postItemActionsMessageIconFinder);
+
+ final postItemActionsMessageIcon = postItemActionsMessageIconFinder
+ .evaluate()
+ .first
+ .widget as SvgPicture;
+ checkByKeyIsWidget(postItemActionsMessageIcon, isA());
+ checkWidgetProperty(
+ "width",
+ postItemActionsMessageIconFinder,
+ postItemActionsMessageIcon.width,
+ 27,
+ );
+ checkWidgetProperty(
+ "pictureProvider.runtimeType",
+ postItemActionsMessageIconFinder,
+ postItemActionsMessageIcon.pictureProvider.runtimeType,
+ ExactAssetPicture,
+ );
+
+ final postItemActionsMessageIconPictureProvider =
+ postItemActionsMessageIcon.pictureProvider as ExactAssetPicture;
+ checkWidgetProperty(
+ "assetName",
+ postItemActionsMessageIconFinder,
+ postItemActionsMessageIconPictureProvider.assetName,
+ "assets/images/message_icon.svg",
+ );
+
+ final postItemActionsSaveIconFinder = find.byKey(
+ const Key('post_item_actions_save_icon'),
+ );
+ checkWidgetDescendantProperty(
+ postItemActionRowFinder, postItemActionsSaveIconFinder);
+
+ final postItemActionsSaveIcon =
+ postItemActionsSaveIconFinder.evaluate().first.widget as SvgPicture;
+ checkByKeyIsWidget(postItemActionsSaveIcon, isA());
+ checkWidgetProperty(
+ "width",
+ postItemActionsSaveIconFinder,
+ postItemActionsSaveIcon.width,
+ 27,
+ );
+ checkWidgetProperty(
+ "pictureProvider.runtimeType",
+ postItemActionsSaveIconFinder,
+ postItemActionsSaveIcon.pictureProvider.runtimeType,
+ ExactAssetPicture);
+
+ final postItemActionsSaveIconPictureProvider =
+ postItemActionsSaveIcon.pictureProvider as ExactAssetPicture;
+ checkWidgetProperty(
+ "assetName",
+ postItemActionsSaveIconFinder,
+ postItemActionsSaveIconPictureProvider.assetName,
+ "assets/images/save_icon.svg",
+ );
+
+ final postItemCaptionContainerFinder = find.byKey(
+ const Key('post_item_caption_container'),
+ );
+ checkWidgetDescendantProperty(
+ postItemColumnFinder,
+ postItemCaptionContainerFinder,
+ );
+
+ final postItemCaptionContainer =
+ postItemCaptionContainerFinder.evaluate().first.widget as Container;
+ checkByKeyIsWidget(postItemCaptionContainer, isA());
+ checkWidgetProperty(
+ "padding",
+ postItemCaptionContainerFinder,
+ postItemCaptionContainer.padding,
+ const EdgeInsets.symmetric(horizontal: 15),
+ );
+ checkWidgetProperty(
+ "margin",
+ postItemCaptionContainerFinder,
+ postItemCaptionContainer.margin,
+ const EdgeInsets.only(bottom: 12),
+ );
+
+ final postItemCaptionRichTextFinder = find.byKey(
+ const Key('post_item_caption_rich_text'),
+ );
+ checkWidgetDescendantProperty(
+ postItemCaptionContainerFinder, postItemCaptionRichTextFinder);
+
+ final postItemCaptionRichText =
+ postItemCaptionRichTextFinder.evaluate().first.widget as RichText;
+ checkByKeyIsWidget(postItemCaptionRichText.text, isA());
+
+ final postItemCaptionRichTextTextSpan =
+ postItemCaptionRichText.text as TextSpan;
+ // checkError(131, postItemCaptionRichTextTextSpan.children, hasLength(2));
+
+ final postItemCaptionRichTextTextSpanTextSpan1 =
+ postItemCaptionRichTextTextSpan.children![0] as TextSpan;
+ checkWidgetProperty(
+ "text",
+ postItemCaptionRichTextTextSpanTextSpan1,
+ postItemCaptionRichTextTextSpanTextSpan1.text,
+ posts[0]['name'] + ' ');
+ checkWidgetProperty(
+ "text",
+ postItemCaptionRichTextTextSpanTextSpan1,
+ postItemCaptionRichTextTextSpanTextSpan1.style,
+ const TextStyle(fontSize: 15, fontWeight: FontWeight.w700),
+ );
+
+ final postItemCaptionRichTextTextSpanTextSpan2 =
+ postItemCaptionRichTextTextSpan.children![1] as TextSpan;
+ checkWidgetProperty("text", postItemCaptionRichTextTextSpanTextSpan2,
+ postItemCaptionRichTextTextSpanTextSpan2.text, posts[0]['caption']);
+ checkWidgetProperty(
+ "text",
+ postItemCaptionRichTextTextSpanTextSpan2,
+ postItemCaptionRichTextTextSpanTextSpan2.style,
+ const TextStyle(fontSize: 15, fontWeight: FontWeight.w500),
+ );
+
+ final postItemViewCommentsContainerFinder = find.byKey(
+ const Key('post_item_view_comments_container'),
+ );
+ checkWidgetDescendantProperty(
+ postItemColumnFinder, postItemViewCommentsContainerFinder);
+
+ final postItemViewCommentsContainer = postItemViewCommentsContainerFinder
+ .evaluate()
+ .first
+ .widget as Container;
+ checkWidgetProperty(
+ "padding",
+ postItemViewCommentsContainerFinder,
+ postItemViewCommentsContainer.padding,
+ const EdgeInsets.symmetric(horizontal: 15),
+ );
+ checkWidgetProperty(
+ "margin",
+ postItemViewCommentsContainerFinder,
+ postItemViewCommentsContainer.margin,
+ const EdgeInsets.only(bottom: 12),
+ );
+
+ final postItemViewCommentsTextFinder = find.byKey(
+ const Key('post_item_view_comments_text'),
+ );
+ checkWidgetDescendantProperty(
+ postItemViewCommentsContainerFinder, postItemViewCommentsTextFinder);
+
+ final postItemViewCommentsText =
+ postItemViewCommentsTextFinder.evaluate().first.widget as Text;
+ checkWidgetProperty(
+ "data",
+ postItemViewCommentsTextFinder,
+ postItemViewCommentsText.data,
+ "View ${posts[0]['commentCount']} comments",
+ );
+ checkByKeyIsWidget(postItemViewCommentsText.style, isA());
+ checkWidgetProperty(
+ "color",
+ postItemViewCommentsTextFinder,
+ postItemViewCommentsText.style!.color,
+ white.withOpacity(0.5),
+ );
+ checkWidgetProperty(
+ "fontSize",
+ postItemViewCommentsTextFinder,
+ postItemViewCommentsText.style!.fontSize,
+ 15,
+ );
+ checkWidgetProperty(
+ "fontWeight",
+ postItemViewCommentsTextFinder,
+ postItemViewCommentsText.style!.fontWeight,
+ FontWeight.w500,
+ );
+
+ final postItemAddCommentContainerFinder = find.byKey(
+ const Key('post_item_add_comment_container'),
+ );
+ checkWidgetDescendantProperty(
+ postItemColumnFinder, postItemAddCommentContainerFinder);
+
+ final postItemAddCommentContainer = postItemAddCommentContainerFinder
+ .evaluate()
+ .first
+ .widget as Container;
+ checkWidgetProperty(
+ "padding",
+ postItemAddCommentContainerFinder,
+ postItemAddCommentContainer.padding,
+ const EdgeInsets.symmetric(horizontal: 15),
+ );
+ checkWidgetProperty(
+ "margin",
+ postItemAddCommentContainerFinder,
+ postItemAddCommentContainer.margin,
+ const EdgeInsets.only(bottom: 12),
+ );
+
+ final postItemAddCommentRowFinder = find.byKey(
+ const Key('post_item_add_comment_row'),
+ );
+ checkWidgetDescendantProperty(
+ postItemAddCommentContainerFinder, postItemAddCommentRowFinder);
+
+ final postItemAddCommentRow =
+ postItemAddCommentRowFinder.evaluate().first.widget as Row;
+ checkWidgetProperty(
+ "mainAxisAlignment",
+ postItemAddCommentRowFinder,
+ postItemAddCommentRow.mainAxisAlignment,
+ MainAxisAlignment.spaceBetween,
+ );
+ // checkError(150, postItemAddCommentRow.children, hasLength(2));
+
+ final postItemAddCommentLeftRowFinder = find.byKey(
+ const Key('post_item_add_comment_left_row'),
+ );
+ checkWidgetDescendantProperty(
+ postItemAddCommentRowFinder, postItemAddCommentLeftRowFinder);
+
+ // final postItemAddCommentLeftRow =
+ // postItemAddCommentLeftRowFinder.evaluate().first.widget as Row;
+ // checkError(152, postItemAddCommentLeftRow.children, hasLength(2));
+
+ final postItemAddCommentAvatarContainerFinder = find.byKey(
+ const Key('post_item_add_comment_avatar_container'),
+ );
+ checkWidgetDescendantProperty(postItemAddCommentLeftRowFinder,
+ postItemAddCommentAvatarContainerFinder);
+
+ final postItemAddCommentAvatarContainer =
+ postItemAddCommentAvatarContainerFinder.evaluate().first.widget
+ as Container;
+ checkWidgetProperty(
+ "width",
+ postItemAddCommentAvatarContainerFinder,
+ postItemAddCommentAvatarContainer.constraints!.widthConstraints(),
+ const BoxConstraints(minWidth: 30, maxWidth: 30),
+ );
+ checkWidgetProperty(
+ "height",
+ postItemAddCommentAvatarContainerFinder,
+ postItemAddCommentAvatarContainer.constraints!.heightConstraints(),
+ const BoxConstraints(minHeight: 30, maxHeight: 30),
+ );
+ checkWidgetProperty(
+ "margin",
+ postItemAddCommentAvatarContainerFinder,
+ postItemAddCommentAvatarContainer.margin,
+ const EdgeInsets.only(right: 15),
+ );
+ checkByKeyIsWidget(
+ postItemAddCommentAvatarContainer.decoration, isA());
+
+ final postItemAddCommentAvatarContainerDecoration =
+ postItemAddCommentAvatarContainer.decoration as BoxDecoration;
+ checkWidgetProperty(
+ "shape",
+ postItemAddCommentAvatarContainerFinder,
+ postItemAddCommentAvatarContainerDecoration.shape,
+ BoxShape.circle,
+ );
+ checkByKeyIsWidget(postItemAddCommentAvatarContainerDecoration.image,
+ isA());
+
+ final postItemAddCommentAvatarContainerDecorationImage =
+ postItemAddCommentAvatarContainerDecoration.image as DecorationImage;
+ checkByKeyIsWidget(postItemAddCommentAvatarContainerDecorationImage.image,
+ isA());
+ checkWidgetProperty(
+ "DecorationImage.fit",
+ postItemAddCommentAvatarContainerFinder,
+ postItemAddCommentAvatarContainerDecorationImage.fit,
+ BoxFit.cover,
+ );
+
+ final postItemAddCommentAvatarContainerDecorationImageNetworkImage =
+ postItemAddCommentAvatarContainerDecorationImage.image
+ as NetworkImage;
+ checkWidgetProperty(
+ "DecorationImageNetworkImage.url",
+ postItemAddCommentAvatarContainerFinder,
+ postItemAddCommentAvatarContainerDecorationImageNetworkImage.url,
+ profile,
+ );
+
+ final postItemAddCommentTextFinder = find.byKey(
+ const Key('post_item_add_comment_text'),
+ );
+ checkWidgetDescendantProperty(
+ postItemAddCommentLeftRowFinder, postItemAddCommentTextFinder);
+
+ final postItemAddCommentText =
+ postItemAddCommentTextFinder.evaluate().first.widget as Text;
+ checkWidgetProperty(
+ "data",
+ postItemAddCommentTextFinder,
+ postItemAddCommentText.data,
+ 'Add a comment...',
+ );
+ checkByKeyIsWidget(postItemAddCommentText.style, isA());
+ checkWidgetProperty(
+ "color",
+ postItemAddCommentTextFinder,
+ postItemAddCommentText.style!.color,
+ white.withOpacity(0.5),
+ );
+ checkWidgetProperty(
+ "fontSize",
+ postItemAddCommentTextFinder,
+ postItemAddCommentText.style!.fontSize,
+ 15,
+ );
+ checkWidgetProperty(
+ "fontWeight",
+ postItemAddCommentTextFinder,
+ postItemAddCommentText.style!.fontWeight,
+ FontWeight.w500,
+ );
+
+ final postItemAddCommentRightRowFinder =
+ find.byKey(const Key('post_item_add_comment_right_row'));
+ checkWidgetDescendantProperty(
+ postItemAddCommentRowFinder, postItemAddCommentRightRowFinder);
+
+ // final postItemAddCommentRightRow =
+ // postItemAddCommentRightRowFinder.evaluate().first.widget as Row;
+ // checkError(170, postItemAddCommentRightRow.children, hasLength(5));
+
+ final postItemAddLaughEmojiTextFinder = find.byKey(
+ const Key('post_item_add_laugh_emoji_text'),
+ );
+ checkWidgetDescendantProperty(
+ postItemAddCommentRightRowFinder, postItemAddLaughEmojiTextFinder);
+
+ final postItemAddLaughEmojiText =
+ postItemAddLaughEmojiTextFinder.evaluate().first.widget as Text;
+ checkWidgetProperty(
+ "data",
+ postItemAddLaughEmojiTextFinder,
+ postItemAddLaughEmojiText.data,
+ '😂',
+ );
+ checkWidgetProperty(
+ "style",
+ postItemAddLaughEmojiTextFinder,
+ postItemAddLaughEmojiText.style,
+ const TextStyle(fontSize: 20),
+ );
+
+ final postItemAddLoveEmojiTextFinder = find.byKey(
+ const Key('post_item_add_love_emoji_text'),
+ );
+ checkWidgetDescendantProperty(
+ postItemAddCommentRightRowFinder, postItemAddLoveEmojiTextFinder);
+
+ final postItemAddLoveEmojiText =
+ postItemAddLoveEmojiTextFinder.evaluate().first.widget as Text;
+ checkWidgetProperty(
+ "data",
+ postItemAddLoveEmojiTextFinder,
+ postItemAddLoveEmojiText.data,
+ '😍',
+ );
+ checkWidgetProperty(
+ "style",
+ postItemAddLoveEmojiTextFinder,
+ postItemAddLoveEmojiText.style,
+ const TextStyle(fontSize: 20),
+ );
+
+ final postItemAddCircleIconFinder = find.byKey(
+ const Key('post_item_add_circle_icon'),
+ );
+ checkWidgetDescendantProperty(
+ postItemAddCommentRightRowFinder, postItemAddCircleIconFinder);
+
+ final postItemAddCircleIcon =
+ postItemAddCircleIconFinder.evaluate().first.widget as Icon;
+ checkWidgetProperty(
+ "icon",
+ postItemAddCircleIconFinder,
+ postItemAddCircleIcon.icon,
+ Icons.add_circle,
+ );
+ checkWidgetProperty(
+ "size",
+ postItemAddCircleIconFinder,
+ postItemAddCircleIcon.size,
+ 18,
+ );
+ checkWidgetProperty(
+ "color",
+ postItemAddCircleIconFinder,
+ postItemAddCircleIcon.color,
+ white.withOpacity(0.5),
+ );
+
+ final postItemDayAgoPaddingFinder = find.byKey(
+ const Key('post_item_day_ago_padding'),
+ );
+ checkWidgetDescendantProperty(
+ postItemColumnFinder, postItemDayAgoPaddingFinder);
+
+ final postItemDayAgoPadding =
+ postItemDayAgoPaddingFinder.evaluate().first.widget as Padding;
+ checkWidgetProperty(
+ "padding",
+ postItemDayAgoPaddingFinder,
+ postItemDayAgoPadding.padding,
+ const EdgeInsets.symmetric(horizontal: 15),
+ );
+
+ final postItemDayAgoTextFinder = find.byKey(
+ const Key('post_item_day_ago_text'),
+ );
+ checkWidgetDescendantProperty(
+ postItemDayAgoPaddingFinder, postItemDayAgoTextFinder);
+
+ final postItemDayAgoText =
+ postItemDayAgoTextFinder.evaluate().first.widget as Text;
+ checkWidgetProperty(
+ "data",
+ postItemDayAgoTextFinder,
+ postItemDayAgoText.data,
+ posts[0]['timeAgo'],
+ );
+ checkWidgetProperty(
+ "color",
+ postItemDayAgoTextFinder,
+ postItemDayAgoText.style!.color,
+ white.withOpacity(0.5),
+ );
+ checkWidgetProperty(
+ "fontSize",
+ postItemDayAgoTextFinder,
+ postItemDayAgoText.style!.fontSize,
+ 15,
+ );
+ checkWidgetProperty(
+ "fontWeight",
+ postItemDayAgoTextFinder,
+ postItemDayAgoText.style!.fontWeight,
+ FontWeight.w500,
+ );
+ },
+ );
+}
diff --git a/clone-instagram-login-Refactoring/test/task_5_test.dart b/clone-instagram-login-Refactoring/test/task_5_test.dart
new file mode 100644
index 0000000..e8f4798
--- /dev/null
+++ b/clone-instagram-login-Refactoring/test/task_5_test.dart
@@ -0,0 +1,1295 @@
+import 'package:example_widget_testing/app/modules/home/components/story_item.dart';
+import 'package:example_widget_testing/app/modules/home/home_page.dart';
+import 'package:example_widget_testing/app/modules/login/login_page.dart';
+import 'package:example_widget_testing/app/widgets/post_item.dart';
+import 'package:example_widget_testing/core/theme/colors.dart';
+import 'package:example_widget_testing/core/values/constant/post_json.dart';
+import 'package:example_widget_testing/core/values/constant/profile_json.dart';
+import 'package:example_widget_testing/core/values/constant/story_json.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:network_image_mock/network_image_mock.dart';
+
+import 'test_library.dart';
+
+void main() {
+ testWidgets('Check if Task 2 is finished', (WidgetTester tester) async {
+ FlutterError.onError = unfinishedTaskErrorHandler;
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ const MaterialApp(
+ home: LoginPage(),
+ ),
+ ),
+ );
+ final loginPageFinder = find.byType(LoginPage);
+ checkByTypeFindOneWidget(loginPageFinder);
+ });
+
+ testWidgets('Check if Task 3 is finished', (WidgetTester tester) async {
+ FlutterError.onError = unfinishedTaskErrorHandler;
+
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ MaterialApp(
+ home: HomePage(
+ posts: posts,
+ profileData: profileJson,
+ stories: stories,
+ ),
+ ),
+ ),
+ );
+ final homePageFinder = find.byType(HomePage);
+ checkByTypeFindOneWidget(homePageFinder);
+
+ final appBarFinder = find.byKey(const Key('home_page_appbar'));
+ checkByKeyFindOneWidget(appBarFinder);
+
+ final appBar = appBarFinder.evaluate().first.widget as AppBar;
+ checkWidgetProperty(
+ "backgroundColor", appBar, appBar.backgroundColor, Colors.black);
+ checkByKeyIsWidget(appBar.leading, isA());
+
+ final appBarLeading = appBar.leading as Icon;
+ checkWidgetProperty("icon", appBar, appBarLeading.icon, Icons.camera_alt);
+ checkByKeyIsWidget(appBar.title, isA());
+
+ final appBarTitle = appBar.title as Center;
+ checkByKeyIsWidget(appBarTitle.child, isA());
+ checkByKeyIsWidget(appBar.actions, isA>());
+ // checkError(9, appBar.actions?.length, 1);
+
+ final appBarAction = appBar.actions?.first as Icon;
+ checkWidgetProperty("icon", appBar, appBarAction.icon, Icons.send);
+
+ final storyFinder = find.byKey(const Key('following_stories_row'));
+ checkByKeyFindOneWidget(storyFinder);
+
+ final story = storyFinder.evaluate().first.widget as Row;
+ checkByKeyIsWidget(story.children, isA>());
+ checkWidgetProperty(
+ "length", storyFinder, story.children.length, stories.length);
+ checkByKeyIsWidget(story.children[0], isA());
+
+ stories.asMap().forEach((index, value) {
+ final storyItem = story.children[index] as StoryItem;
+ checkWidgetProperty("name", storyFinder, storyItem.name, value['name']);
+ checkWidgetProperty("img", storyFinder, storyItem.img, value['img']);
+ });
+
+ const String imageUrl = 'https://example.com/image.jpg';
+ const String name = 'John Doe';
+
+ FlutterError.onError = customFlutterErrorHandler;
+
+ await mockNetworkImagesFor(() => tester.pumpWidget(
+ const MaterialApp(home: StoryItem(img: imageUrl, name: name))));
+
+ // checkError(17, find.byType(Container), findsNWidgets(2));
+
+ final storyItemPaddingFinder = find.byKey(const Key('story_item_padding'));
+ checkByKeyFindOneWidget(storyItemPaddingFinder);
+
+ final storyItemPadding =
+ storyItemPaddingFinder.evaluate().first.widget as Padding;
+ checkWidgetProperty(
+ "padding",
+ storyItemPaddingFinder,
+ storyItemPadding.padding,
+ const EdgeInsets.only(right: 20, bottom: 10),
+ );
+
+ final storyItemColumnFinder = find.byKey(const Key('story_item_column'));
+ checkByKeyFindOneWidget(storyItemColumnFinder);
+ checkWidgetDescendantProperty(
+ storyItemPaddingFinder, storyItemColumnFinder);
+
+ final storyItemColumn =
+ storyItemColumnFinder.evaluate().first.widget as Column;
+ checkByKeyIsWidget(storyItemColumn.children, isA>());
+ // checkError(23, storyItemColumn.children.length, 2);
+
+ final storyItemContainerFinder = find.byKey(
+ const Key('story_item_container'),
+ );
+ checkWidgetDescendantProperty(
+ storyItemColumnFinder, storyItemContainerFinder);
+
+ final storyItemContainer =
+ storyItemContainerFinder.evaluate().first.widget as Container;
+
+ checkWidgetProperty(
+ "width",
+ storyItemContainerFinder,
+ storyItemContainer.constraints!.widthConstraints(),
+ const BoxConstraints(minWidth: 68, maxWidth: 68),
+ );
+
+ checkWidgetProperty(
+ "margin",
+ storyItemContainerFinder,
+ storyItemContainer.margin,
+ const EdgeInsets.only(bottom: 8),
+ );
+
+ checkWidgetProperty(
+ "height",
+ storyItemContainerFinder,
+ storyItemContainer.constraints!.heightConstraints(),
+ const BoxConstraints(minHeight: 68, maxHeight: 68),
+ );
+
+ checkByKeyIsWidget(storyItemContainer.decoration, isA());
+
+ final storyItemContainerDecoration =
+ storyItemContainer.decoration as BoxDecoration;
+ checkWidgetProperty(
+ "shape",
+ storyItemContainerFinder,
+ storyItemContainerDecoration.shape,
+ BoxShape.circle,
+ );
+
+ checkByKeyIsWidget(
+ storyItemContainerDecoration.gradient, isA());
+ final storyItemContainerGradient =
+ storyItemContainerDecoration.gradient as LinearGradient;
+ checkWidgetProperty(
+ "begin",
+ storyItemContainerFinder,
+ storyItemContainerGradient.begin,
+ Alignment.topCenter,
+ );
+ checkWidgetProperty(
+ 'end',
+ storyItemContainerFinder,
+ storyItemContainerGradient.end,
+ Alignment.bottomCenter,
+ );
+ checkWidgetProperty(
+ "colors",
+ storyItemContainerFinder,
+ storyItemContainerGradient.colors,
+ const [Color(0xFF9B2282), Color(0xFFEEA863)],
+ );
+
+ final storyItemImageContainerFinder = find.byKey(
+ const Key('story_item_image_container'),
+ );
+
+ checkWidgetDescendantProperty(
+ storyItemContainerFinder, storyItemImageContainerFinder);
+
+ final storyItemImageContainer =
+ storyItemImageContainerFinder.evaluate().first.widget as Container;
+
+ checkWidgetProperty(
+ "width",
+ storyItemImageContainerFinder,
+ storyItemImageContainer.constraints!.widthConstraints(),
+ const BoxConstraints(minWidth: 65, maxWidth: 65),
+ );
+
+ checkWidgetProperty(
+ "height",
+ storyItemImageContainerFinder,
+ storyItemImageContainer.constraints!.heightConstraints(),
+ const BoxConstraints(minHeight: 65, maxHeight: 65),
+ );
+
+ checkWidgetProperty(
+ "margin",
+ storyItemImageContainerFinder,
+ storyItemImageContainer.margin,
+ const EdgeInsets.all(3),
+ );
+
+ checkByKeyIsWidget(
+ storyItemImageContainer.decoration, isA());
+
+ final storyItemImageContainerDecoration =
+ storyItemImageContainer.decoration as BoxDecoration;
+ checkWidgetProperty(
+ "shape",
+ storyItemImageContainerFinder,
+ storyItemImageContainerDecoration.shape,
+ BoxShape.circle,
+ );
+ checkWidgetProperty(
+ "border",
+ storyItemImageContainerFinder,
+ storyItemImageContainerDecoration.border,
+ const Border.fromBorderSide(
+ BorderSide(
+ color: black,
+ width: 2,
+ style: BorderStyle.solid,
+ ),
+ ),
+ );
+
+ checkByKeyIsWidget(
+ storyItemImageContainerDecoration.image, isA());
+
+ final storyItemImageContainerDecorationImage =
+ (storyItemImageContainer.decoration as BoxDecoration).image
+ as DecorationImage;
+ checkByKeyIsWidget(
+ storyItemImageContainerDecorationImage.image, isA());
+
+ checkWidgetProperty(
+ "fit",
+ storyItemImageContainerFinder,
+ storyItemImageContainerDecorationImage.fit,
+ BoxFit.cover,
+ );
+
+ final storyItemUsernameSizeBoxFinder = find.byKey(
+ const Key('story_item_username_sizedbox'),
+ );
+
+ checkWidgetDescendantProperty(
+ storyItemColumnFinder, storyItemUsernameSizeBoxFinder);
+
+ final storyItemUsernameSizeBox =
+ storyItemUsernameSizeBoxFinder.evaluate().first.widget as SizedBox;
+ checkWidgetProperty(
+ "width",
+ storyItemUsernameSizeBoxFinder,
+ storyItemUsernameSizeBox.width,
+ 70,
+ );
+
+ final storyItemUsernameTextFinder = find.byKey(
+ const Key('story_item_username_text'),
+ );
+
+ checkWidgetDescendantProperty(
+ storyItemUsernameSizeBoxFinder, storyItemUsernameTextFinder);
+
+ final storyItemUsernameText =
+ storyItemUsernameTextFinder.evaluate().first.widget as Text;
+ checkWidgetProperty(
+ "data",
+ storyItemUsernameTextFinder,
+ storyItemUsernameText.data,
+ name,
+ );
+ checkWidgetProperty(
+ "overflow",
+ storyItemUsernameTextFinder,
+ storyItemUsernameText.overflow,
+ TextOverflow.ellipsis,
+ );
+ checkWidgetProperty(
+ "color",
+ storyItemUsernameTextFinder,
+ storyItemUsernameText.style!.color,
+ white,
+ );
+
+ await tester.pumpWidget(
+ MaterialApp(
+ home: HomePage(
+ posts: posts,
+ profileData: profileJson,
+ stories: stories,
+ ),
+ ),
+ );
+
+ final dividerFinder = find.byKey(const Key('home_page_divider'));
+ checkByKeyFindOneWidget(dividerFinder);
+
+ final divider = dividerFinder.evaluate().first.widget as Divider;
+ checkWidgetProperty(
+ "color",
+ dividerFinder,
+ divider.color,
+ white.withOpacity(0.3),
+ );
+ });
+
+ testWidgets('Check if Task 4 is finished', (WidgetTester tester) async {
+ FlutterError.onError = unfinishedTaskErrorHandler;
+
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ MaterialApp(
+ home: HomePage(
+ posts: posts,
+ profileData: profileJson,
+ stories: stories,
+ ),
+ ),
+ ),
+ );
+
+ final homePageColumnFinder = find.byKey(const Key('home_page_column'));
+ final postsColumnFinder = find.byKey(const Key('posts_column'));
+ checkWidgetDescendantProperty(homePageColumnFinder, postsColumnFinder);
+ checkByKeyFindOneWidget(postsColumnFinder);
+
+ final postsColumn = postsColumnFinder.evaluate().first.widget as Column;
+ checkError(53, postsColumn.children.length, posts.length);
+
+ await mockNetworkImagesFor(
+ () => tester.pumpWidget(
+ MaterialApp(
+ home: PostItem(
+ postImg: posts[0]['postImg'],
+ profileImg: posts[0]['profileImg'],
+ name: posts[0]['name'],
+ caption: posts[0]['caption'],
+ isLoved: posts[0]['isLoved'],
+ viewCount: posts[0]['commentCount'],
+ likedBy: posts[0]['likedBy'],
+ dayAgo: posts[0]['timeAgo'],
+ userPhoto: profile,
+ onPressed: () {},
+ ),
+ ),
+ ),
+ );
+
+ final postItemPaddingFinder = find.byKey(const Key('post_item_padding'));
+ checkByKeyFindOneWidget(postItemPaddingFinder);
+
+ final postItemPadding =
+ postItemPaddingFinder.evaluate().first.widget as Padding;
+ checkWidgetProperty(
+ "padding",
+ postItemPaddingFinder,
+ postItemPadding.padding,
+ const EdgeInsets.only(bottom: 10),
+ );
+
+ final postItemColumnFinder = find.byKey(const Key('post_item_column'));
+ checkWidgetDescendantProperty(postItemPaddingFinder, postItemColumnFinder);
+
+ final postItemColumn =
+ postItemColumnFinder.evaluate().first.widget as Column;
+ checkWidgetProperty(
+ "crossAxisAlignment",
+ postItemColumnFinder,
+ postItemColumn.crossAxisAlignment,
+ CrossAxisAlignment.start,
+ );
+ // checkError(58, postItemColumn.children.length, 8);
+
+ final postItemUserInfoContainerFinder = find.byKey(
+ const Key('post_item_user_info_container'),
+ );
+ checkWidgetDescendantProperty(
+ postItemColumnFinder, postItemUserInfoContainerFinder);
+
+ final postItemUserInfoContainer =
+ postItemUserInfoContainerFinder.evaluate().first.widget as Container;
+ checkWidgetProperty(
+ "padding",
+ postItemUserInfoContainerFinder,
+ postItemUserInfoContainer.padding,
+ const EdgeInsets.symmetric(vertical: 10, horizontal: 15),
+ );
+
+ checkWidgetProperty(
+ "margin",
+ postItemUserInfoContainerFinder,
+ postItemUserInfoContainer.margin,
+ const EdgeInsets.only(bottom: 12),
+ );
+
+ final postItemUserInfoRowFinder = find.byKey(
+ const Key('post_item_user_info_row'),
+ );
+ checkWidgetDescendantProperty(
+ postItemUserInfoContainerFinder, postItemUserInfoRowFinder);
+
+ final postItemUserInfoRow =
+ postItemUserInfoRowFinder.evaluate().first.widget as Row;
+ checkWidgetProperty(
+ "mainAxisAlignment",
+ postItemUserInfoRowFinder,
+ postItemUserInfoRow.mainAxisAlignment,
+ MainAxisAlignment.spaceBetween,
+ );
+ // checkError(64, postItemUserInfoRow.children.length, 3);
+
+ final postItemUserImgContainerFinder = find.byKey(
+ const Key('post_item_user_profile_img_container'),
+ );
+ checkWidgetDescendantProperty(
+ postItemUserInfoRowFinder, postItemUserImgContainerFinder);
+
+ final postItemUserImgContainer =
+ postItemUserImgContainerFinder.evaluate().first.widget as Container;
+ checkWidgetProperty(
+ "width",
+ postItemUserImgContainerFinder,
+ postItemUserImgContainer.constraints!.maxWidth,
+ 40,
+ );
+ checkWidgetProperty(
+ "height",
+ postItemUserImgContainerFinder,
+ postItemUserImgContainer.constraints!.maxHeight,
+ 40,
+ );
+ checkWidgetProperty(
+ "margin",
+ postItemUserImgContainerFinder,
+ postItemUserImgContainer.margin,
+ const EdgeInsets.only(right: 15),
+ );
+ checkByKeyIsWidget(
+ postItemUserImgContainer.decoration, isA());
+
+ final postItemUserImgContainerDecoration =
+ postItemUserImgContainer.decoration as BoxDecoration;
+ checkWidgetProperty(
+ "shape",
+ postItemUserImgContainerFinder,
+ postItemUserImgContainerDecoration.shape,
+ BoxShape.circle,
+ );
+ checkByKeyIsWidget(
+ postItemUserImgContainerDecoration.image,
+ isA(),
+ );
+
+ final postItemUserImgContainerDecorationImage =
+ postItemUserImgContainerDecoration.image as DecorationImage;
+ checkByKeyIsWidget(
+ postItemUserImgContainerDecorationImage.image, isA());
+ checkWidgetProperty(
+ "fit",
+ postItemUserImgContainerFinder,
+ postItemUserImgContainerDecorationImage.fit,
+ BoxFit.cover,
+ );
+
+ final postItemUserImgContainerDecorationImageNetworkImage =
+ postItemUserImgContainerDecorationImage.image as NetworkImage;
+ checkWidgetProperty(
+ "ImageNetworkImage.url",
+ postItemUserImgContainerFinder,
+ postItemUserImgContainerDecorationImageNetworkImage.url,
+ posts[0]['profileImg'],
+ );
+
+ final postItemUserNameExpendedFinder = find.byKey(
+ const Key('post_item_user_name_expanded'),
+ );
+ checkWidgetDescendantProperty(
+ postItemUserInfoRowFinder, postItemUserNameExpendedFinder);
+
+ final postItemUserNameTextFinder = find.byKey(
+ const Key('post_item_user_name_text'),
+ );
+ checkWidgetDescendantProperty(
+ postItemUserNameExpendedFinder, postItemUserNameTextFinder);
+
+ final postItemUserNameText =
+ postItemUserNameTextFinder.evaluate().first.widget as Text;
+ checkWidgetProperty(
+ "data",
+ postItemUserNameTextFinder,
+ postItemUserNameText.data,
+ posts[0]['name'],
+ );
+ checkByKeyIsWidget(postItemUserNameText.style, isA