diff --git a/ai_friend/.dart_tool/dartpad/web_plugin_registrant.dart b/ai_friend/.dart_tool/dartpad/web_plugin_registrant.dart deleted file mode 100644 index fd546bf..0000000 --- a/ai_friend/.dart_tool/dartpad/web_plugin_registrant.dart +++ /dev/null @@ -1,8 +0,0 @@ -// Flutter web plugin registrant file. -// -// Generated file. Do not edit. -// - -// ignore_for_file: type=lint - -void registerPlugins() {} diff --git a/ai_friend/.dart_tool/package_config.json b/ai_friend/.dart_tool/package_config.json deleted file mode 100644 index dd03508..0000000 --- a/ai_friend/.dart_tool/package_config.json +++ /dev/null @@ -1,179 +0,0 @@ -{ - "configVersion": 2, - "packages": [ - { - "name": "async", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/async-2.12.0", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "boolean_selector", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/boolean_selector-2.1.2", - "packageUri": "lib/", - "languageVersion": "3.1" - }, - { - "name": "characters", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/characters-1.4.0", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "clock", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/clock-1.1.2", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "collection", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/collection-1.19.1", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "cupertino_icons", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/cupertino_icons-1.0.8", - "packageUri": "lib/", - "languageVersion": "3.1" - }, - { - "name": "fake_async", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/fake_async-1.3.2", - "packageUri": "lib/", - "languageVersion": "3.3" - }, - { - "name": "flutter", - "rootUri": "file:///C:/flutter/flutter/packages/flutter", - "packageUri": "lib/", - "languageVersion": "3.7" - }, - { - "name": "flutter_lints", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/flutter_lints-5.0.0", - "packageUri": "lib/", - "languageVersion": "3.5" - }, - { - "name": "flutter_test", - "rootUri": "file:///C:/flutter/flutter/packages/flutter_test", - "packageUri": "lib/", - "languageVersion": "3.7" - }, - { - "name": "leak_tracker", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/leak_tracker-10.0.8", - "packageUri": "lib/", - "languageVersion": "3.2" - }, - { - "name": "leak_tracker_flutter_testing", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/leak_tracker_flutter_testing-3.0.9", - "packageUri": "lib/", - "languageVersion": "3.2" - }, - { - "name": "leak_tracker_testing", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/leak_tracker_testing-3.0.1", - "packageUri": "lib/", - "languageVersion": "3.2" - }, - { - "name": "lints", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/lints-5.1.1", - "packageUri": "lib/", - "languageVersion": "3.6" - }, - { - "name": "matcher", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/matcher-0.12.17", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "material_color_utilities", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/material_color_utilities-0.11.1", - "packageUri": "lib/", - "languageVersion": "2.17" - }, - { - "name": "meta", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/meta-1.16.0", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "path", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/path-1.9.1", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "sky_engine", - "rootUri": "file:///C:/flutter/flutter/bin/cache/pkg/sky_engine", - "packageUri": "lib/", - "languageVersion": "3.7" - }, - { - "name": "source_span", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/source_span-1.10.1", - "packageUri": "lib/", - "languageVersion": "3.1" - }, - { - "name": "stack_trace", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/stack_trace-1.12.1", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "stream_channel", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/stream_channel-2.1.4", - "packageUri": "lib/", - "languageVersion": "3.3" - }, - { - "name": "string_scanner", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/string_scanner-1.4.1", - "packageUri": "lib/", - "languageVersion": "3.1" - }, - { - "name": "term_glyph", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/term_glyph-1.2.2", - "packageUri": "lib/", - "languageVersion": "3.1" - }, - { - "name": "test_api", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/test_api-0.7.4", - "packageUri": "lib/", - "languageVersion": "3.5" - }, - { - "name": "vector_math", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/vector_math-2.1.4", - "packageUri": "lib/", - "languageVersion": "2.14" - }, - { - "name": "vm_service", - "rootUri": "file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/vm_service-14.3.1", - "packageUri": "lib/", - "languageVersion": "3.3" - }, - { - "name": "ai_friend", - "rootUri": "../", - "packageUri": "lib/", - "languageVersion": "3.6" - } - ], - "generated": "2025-02-27T18:34:50.206730Z", - "generator": "pub", - "generatorVersion": "3.7.0", - "flutterRoot": "file:///C:/flutter/flutter", - "flutterVersion": "3.29.0", - "pubCache": "file:///C:/Users/sachi/AppData/Local/Pub/Cache" -} diff --git a/ai_friend/.dart_tool/package_config_subset b/ai_friend/.dart_tool/package_config_subset deleted file mode 100644 index d9f0ebd..0000000 --- a/ai_friend/.dart_tool/package_config_subset +++ /dev/null @@ -1,113 +0,0 @@ -async -3.4 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/async-2.12.0/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/async-2.12.0/lib/ -boolean_selector -3.1 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/boolean_selector-2.1.2/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/boolean_selector-2.1.2/lib/ -characters -3.4 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/characters-1.4.0/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/characters-1.4.0/lib/ -clock -3.4 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/clock-1.1.2/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/clock-1.1.2/lib/ -collection -3.4 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/collection-1.19.1/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/collection-1.19.1/lib/ -cupertino_icons -3.1 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/cupertino_icons-1.0.8/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/cupertino_icons-1.0.8/lib/ -fake_async -3.3 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/fake_async-1.3.2/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/fake_async-1.3.2/lib/ -flutter_lints -3.5 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/flutter_lints-5.0.0/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/flutter_lints-5.0.0/lib/ -leak_tracker -3.2 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/leak_tracker-10.0.8/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/leak_tracker-10.0.8/lib/ -leak_tracker_flutter_testing -3.2 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/leak_tracker_flutter_testing-3.0.9/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/leak_tracker_flutter_testing-3.0.9/lib/ -leak_tracker_testing -3.2 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/leak_tracker_testing-3.0.1/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/leak_tracker_testing-3.0.1/lib/ -lints -3.6 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/lints-5.1.1/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/lints-5.1.1/lib/ -matcher -3.4 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/matcher-0.12.17/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/matcher-0.12.17/lib/ -material_color_utilities -2.17 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/material_color_utilities-0.11.1/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/material_color_utilities-0.11.1/lib/ -meta -2.12 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/meta-1.16.0/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/meta-1.16.0/lib/ -path -3.4 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/path-1.9.1/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/path-1.9.1/lib/ -source_span -3.1 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/source_span-1.10.1/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/source_span-1.10.1/lib/ -stack_trace -3.4 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/stack_trace-1.12.1/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/stack_trace-1.12.1/lib/ -stream_channel -3.3 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/stream_channel-2.1.4/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/stream_channel-2.1.4/lib/ -string_scanner -3.1 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/string_scanner-1.4.1/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/string_scanner-1.4.1/lib/ -term_glyph -3.1 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/term_glyph-1.2.2/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/term_glyph-1.2.2/lib/ -test_api -3.5 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/test_api-0.7.4/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/test_api-0.7.4/lib/ -vector_math -2.14 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/vector_math-2.1.4/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/vector_math-2.1.4/lib/ -vm_service -3.3 -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/vm_service-14.3.1/ -file:///C:/Users/sachi/AppData/Local/Pub/Cache/hosted/pub.dev/vm_service-14.3.1/lib/ -sky_engine -3.7 -file:///C:/flutter/flutter/bin/cache/pkg/sky_engine/ -file:///C:/flutter/flutter/bin/cache/pkg/sky_engine/lib/ -flutter -3.7 -file:///C:/flutter/flutter/packages/flutter/ -file:///C:/flutter/flutter/packages/flutter/lib/ -flutter_test -3.7 -file:///C:/flutter/flutter/packages/flutter_test/ -file:///C:/flutter/flutter/packages/flutter_test/lib/ -ai_friend -3.6 -file:///D:/1.%20Uni%20work/2nd%20Year/2nd%20Sem/Computing%20group%20project/Computing-Group-Project/Computing-Group-Project/ai_friend/ -file:///D:/1.%20Uni%20work/2nd%20Year/2nd%20Sem/Computing%20group%20project/Computing-Group-Project/Computing-Group-Project/ai_friend/lib/ -2 diff --git a/ai_friend/.dart_tool/version b/ai_friend/.dart_tool/version deleted file mode 100644 index ec131a8..0000000 --- a/ai_friend/.dart_tool/version +++ /dev/null @@ -1 +0,0 @@ -3.29.0 \ No newline at end of file diff --git a/ai_friend/.idea/libraries/Dart_SDK.xml b/ai_friend/.idea/libraries/Dart_SDK.xml deleted file mode 100644 index 9a6b534..0000000 --- a/ai_friend/.idea/libraries/Dart_SDK.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ai_friend/.idea/libraries/KotlinJavaRuntime.xml b/ai_friend/.idea/libraries/KotlinJavaRuntime.xml deleted file mode 100644 index 2b96ac4..0000000 --- a/ai_friend/.idea/libraries/KotlinJavaRuntime.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/ai_friend/.idea/modules.xml b/ai_friend/.idea/modules.xml deleted file mode 100644 index 52d2c7e..0000000 --- a/ai_friend/.idea/modules.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/ai_friend/.idea/runConfigurations/main_dart.xml b/ai_friend/.idea/runConfigurations/main_dart.xml deleted file mode 100644 index aab7b5c..0000000 --- a/ai_friend/.idea/runConfigurations/main_dart.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/ai_friend/.idea/workspace.xml b/ai_friend/.idea/workspace.xml deleted file mode 100644 index 5b3388c..0000000 --- a/ai_friend/.idea/workspace.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ai_friend/ai_friend.iml b/ai_friend/ai_friend.iml deleted file mode 100644 index f66303d..0000000 --- a/ai_friend/ai_friend.iml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/ai_friend/android/ai_friend_android.iml b/ai_friend/android/ai_friend_android.iml deleted file mode 100644 index 1899969..0000000 --- a/ai_friend/android/ai_friend_android.iml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/ai_friend/android/app/build.gradle b/ai_friend/android/app/build.gradle index 96df405..26ab3f3 100644 --- a/ai_friend/android/app/build.gradle +++ b/ai_friend/android/app/build.gradle @@ -3,6 +3,7 @@ plugins { id "kotlin-android" // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. id "dev.flutter.flutter-gradle-plugin" + id 'com.google.gms.google-services' } android { diff --git a/ai_friend/android/app/google-services.json b/ai_friend/android/app/google-services.json new file mode 100644 index 0000000..379a50c --- /dev/null +++ b/ai_friend/android/app/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "802236943000", + "project_id": "nancy-the-ai", + "storage_bucket": "nancy-the-ai.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:802236943000:android:7ac849c5a287cb77385eed", + "android_client_info": { + "package_name": "com.example.ai_friend" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyCUGjej80mzRxpAt7ujOMdqGbnk6BdBCHQ" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/ai_friend/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/ai_friend/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java deleted file mode 100644 index 539ab02..0000000 --- a/ai_friend/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.flutter.plugins; - -import androidx.annotation.Keep; -import androidx.annotation.NonNull; -import io.flutter.Log; - -import io.flutter.embedding.engine.FlutterEngine; - -/** - * Generated file. Do not edit. - * This file is generated by the Flutter tool based on the - * plugins that support the Android platform. - */ -@Keep -public final class GeneratedPluginRegistrant { - private static final String TAG = "GeneratedPluginRegistrant"; - public static void registerWith(@NonNull FlutterEngine flutterEngine) { - } -} diff --git a/ai_friend/android/gradle/wrapper/gradle-wrapper.jar b/ai_friend/android/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 13372ae..0000000 Binary files a/ai_friend/android/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/ai_friend/android/gradlew b/ai_friend/android/gradlew deleted file mode 100644 index 9d82f78..0000000 --- a/ai_friend/android/gradlew +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/ai_friend/android/gradlew.bat b/ai_friend/android/gradlew.bat deleted file mode 100644 index 8a0b282..0000000 --- a/ai_friend/android/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/ai_friend/android/local.properties b/ai_friend/android/local.properties deleted file mode 100644 index 49cd717..0000000 --- a/ai_friend/android/local.properties +++ /dev/null @@ -1,5 +0,0 @@ -sdk.dir=C:\\Users\\sachi\\AppData\\Local\\Android\\sdk -flutter.sdk=C:\\flutter\\flutter -flutter.buildMode=debug -flutter.versionName=1.0.0 -flutter.versionCode=1 \ No newline at end of file diff --git a/ai_friend/android/settings.gradle b/ai_friend/android/settings.gradle index b9e43bd..7b265a4 100644 --- a/ai_friend/android/settings.gradle +++ b/ai_friend/android/settings.gradle @@ -19,7 +19,8 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "com.android.application" version "8.1.0" apply false - id "org.jetbrains.kotlin.android" version "1.8.22" apply false + id "org.jetbrains.kotlin.android" version "2.1.10" apply false + id 'com.google.gms.google-services' version '4.4.2' apply false } include ":app" diff --git a/ai_friend/ios/Flutter/Generated.xcconfig b/ai_friend/ios/Flutter/Generated.xcconfig deleted file mode 100644 index 54687bc..0000000 --- a/ai_friend/ios/Flutter/Generated.xcconfig +++ /dev/null @@ -1,14 +0,0 @@ -// This is a generated file; do not edit or check into version control. -FLUTTER_ROOT=C:\src\flutter_windows_3.10.5-stable\flutter -FLUTTER_APPLICATION_PATH=C:\Users\USER\Documents\GitHub\Computing-Group-Project\ai_friend -COCOAPODS_PARALLEL_CODE_SIGN=true -FLUTTER_TARGET=lib\main.dart -FLUTTER_BUILD_DIR=build -FLUTTER_BUILD_NAME=1.0.0 -FLUTTER_BUILD_NUMBER=1 -EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386 -EXCLUDED_ARCHS[sdk=iphoneos*]=armv7 -DART_OBFUSCATION=false -TRACK_WIDGET_CREATION=true -TREE_SHAKE_ICONS=false -PACKAGE_CONFIG=.dart_tool/package_config.json diff --git a/ai_friend/ios/Flutter/flutter_export_environment.sh b/ai_friend/ios/Flutter/flutter_export_environment.sh deleted file mode 100644 index fa895c9..0000000 --- a/ai_friend/ios/Flutter/flutter_export_environment.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# This is a generated file; do not edit or check into version control. -export "FLUTTER_ROOT=C:\src\flutter_windows_3.10.5-stable\flutter" -export "FLUTTER_APPLICATION_PATH=C:\Users\USER\Documents\GitHub\Computing-Group-Project\ai_friend" -export "COCOAPODS_PARALLEL_CODE_SIGN=true" -export "FLUTTER_TARGET=lib\main.dart" -export "FLUTTER_BUILD_DIR=build" -export "FLUTTER_BUILD_NAME=1.0.0" -export "FLUTTER_BUILD_NUMBER=1" -export "DART_OBFUSCATION=false" -export "TRACK_WIDGET_CREATION=true" -export "TREE_SHAKE_ICONS=false" -export "PACKAGE_CONFIG=.dart_tool/package_config.json" diff --git a/ai_friend/ios/Runner/GeneratedPluginRegistrant.h b/ai_friend/ios/Runner/GeneratedPluginRegistrant.h deleted file mode 100644 index 7a89092..0000000 --- a/ai_friend/ios/Runner/GeneratedPluginRegistrant.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GeneratedPluginRegistrant_h -#define GeneratedPluginRegistrant_h - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface GeneratedPluginRegistrant : NSObject -+ (void)registerWithRegistry:(NSObject*)registry; -@end - -NS_ASSUME_NONNULL_END -#endif /* GeneratedPluginRegistrant_h */ diff --git a/ai_friend/ios/Runner/GeneratedPluginRegistrant.m b/ai_friend/ios/Runner/GeneratedPluginRegistrant.m deleted file mode 100644 index efe65ec..0000000 --- a/ai_friend/ios/Runner/GeneratedPluginRegistrant.m +++ /dev/null @@ -1,14 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#import "GeneratedPluginRegistrant.h" - -@implementation GeneratedPluginRegistrant - -+ (void)registerWithRegistry:(NSObject*)registry { -} - -@end diff --git a/ai_friend/lib/ai_gender.dart b/ai_friend/lib/ai_gender.dart new file mode 100644 index 0000000..0ce3c28 --- /dev/null +++ b/ai_friend/lib/ai_gender.dart @@ -0,0 +1,137 @@ +import 'package:ai_friend/ai_name.dart'; +import 'package:flutter/material.dart'; + +class GenderSelectionPage extends StatefulWidget { + final String name; + final int age; + final String pronouns; + final String freeTime; + final String movieType; + + const GenderSelectionPage({ + super.key, + required this.name, + required this.age, + required this.pronouns, + required this.freeTime, + required this.movieType, + }); + + @override + State createState() => _GenderSelectionPageState(); +} + +class _GenderSelectionPageState extends State { + String? selectedGender; + bool isButtonEnabled = false; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF1C1A3B), // Consistent dark background + body: SafeArea( + child: Column( + children: [ + const SizedBox(height: 40), + Align( + alignment: Alignment.centerLeft, + child: IconButton( + icon: const Icon(Icons.arrow_back, color: Colors.white), + onPressed: () => Navigator.pop(context), + ), + ), + const SizedBox(height: 40), + const Align( + alignment: Alignment.center, + child: Text( + 'What gender do you want\nyour AI friend to be?', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold, + fontFamily: 'PoetsenOne', + ), + ), + ), + const SizedBox(height: 50), + _buildGenderButton("Female"), + const SizedBox(height: 16), + _buildGenderButton("Male"), + const SizedBox(height: 16), + _buildGenderButton("Non-binary"), + const Spacer(), + SizedBox( + width: 275, + height: 64, + child: ElevatedButton( + onPressed: isButtonEnabled + ? () { + // Navigate to next screen with all collected data + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => NameAIFriendPage( + name: widget.name, + age: widget.age, + pronouns: widget.pronouns, + freeTime: widget.freeTime, + movieType: widget.movieType, + aiGender: selectedGender!, + ), + ), + ); + } + : null, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF6E7191), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(40), + ), + ), + child: const Text( + 'Continue', + style: TextStyle( + color: Colors.black, + fontSize: 24, + fontFamily: 'PoetsenOne', + ), + ), + ), + ), + const SizedBox(height: 40), + ], + ), + ), + ); + } + + Widget _buildGenderButton(String gender) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 32), + child: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: + selectedGender == gender ? Colors.blue : const Color(0xFF6E7191), + foregroundColor: Colors.white, + minimumSize: const Size(double.infinity, 60), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + ), + onPressed: () { + setState(() { + selectedGender = gender; + isButtonEnabled = true; + }); + }, + child: Text( + gender, + style: const TextStyle( + fontSize: 18, + fontFamily: 'PoetsenOne', + ), + ), + ), + ); + } +} diff --git a/ai_friend/lib/ai_name.dart b/ai_friend/lib/ai_name.dart new file mode 100644 index 0000000..99d7997 --- /dev/null +++ b/ai_friend/lib/ai_name.dart @@ -0,0 +1,176 @@ +import 'package:ai_friend/chatscreen.dart'; +import 'package:flutter/material.dart'; +//import 'package:firebase_core/firebase_core.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:ai_friend/backend/collect_data.dart'; + +class NameAIFriendPage extends StatefulWidget { + final String name; + final int age; + final String pronouns; + final String freeTime; + final String movieType; + final String aiGender; + + const NameAIFriendPage({ + super.key, + required this.name, + required this.age, + required this.pronouns, + required this.freeTime, + required this.movieType, + required this.aiGender, + }); + + @override + State createState() => _NameAIFriendPageState(); +} + +class _NameAIFriendPageState extends State { + final TextEditingController _nameController = TextEditingController(); + bool isButtonEnabled = false; + + Future _sendUserDataToFirebase(UserData userData) async { + try { + final firestore = FirebaseFirestore.instance; + await firestore + .collection('users') + .add(userData.toJson()); // Auto-generates document ID + return true; + } catch (e) { + print('Firestore Error: $e'); + return false; + } + } + + @override + void initState() { + super.initState(); + _nameController.addListener(_checkInput); + } + + void _checkInput() { + setState(() { + isButtonEnabled = _nameController.text.isNotEmpty; + }); + } + + @override + void dispose() { + _nameController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF1C1A3B), + body: SafeArea( + child: Column( + children: [ + const SizedBox(height: 40), + Align( + alignment: Alignment.centerLeft, + child: IconButton( + icon: const Icon(Icons.arrow_back, color: Colors.white), + onPressed: () => Navigator.pop(context), + ), + ), + const SizedBox(height: 40), + const Text( + 'Name your AI friend', + style: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold, + fontFamily: 'PoetsenOne', + ), + ), + const SizedBox(height: 50), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 32), + child: TextField( + controller: _nameController, + style: const TextStyle( + color: Colors.white, + fontSize: 28, + fontFamily: 'PoetsenOne', + ), + decoration: const InputDecoration( + hintText: 'Enter name', + hintStyle: TextStyle( + color: Color(0xFF6E7191), + fontSize: 28, + fontFamily: 'PoetsenOne', + ), + border: InputBorder.none, + ), + ), + ), + const Spacer(), + SizedBox( + width: 275, + height: 64, + child: ElevatedButton( + onPressed: isButtonEnabled + ? () async { + final userData = UserData( + name: widget.name, + age: widget.age, + pronouns: widget.pronouns, + movieType: widget.movieType, + freeTime: widget.freeTime, + aiName: _nameController.text.trim(), + aiGender: widget.aiGender, + ); + + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => const Center( + child: CircularProgressIndicator(), + ), + ); + + final success = await _sendUserDataToFirebase(userData); + Navigator.pop(context); // Close loading dialog + + if (success) { + Navigator.pushReplacement( + context, + MaterialPageRoute(builder: (_) => ChatScreen()), + ); + } else { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + 'Failed to save data. Please try again.'), + backgroundColor: Colors.red, + ), + ); + } + } + : null, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF6E7191), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(40), + ), + ), + child: const Text( + 'Continue', + style: TextStyle( + color: Colors.black, + fontSize: 24, + fontFamily: 'PoetsenOne', + ), + ), + ), + ), + const SizedBox(height: 40), + ], + ), + ), + ); + } +} diff --git a/ai_friend/lib/backend/backend.py b/ai_friend/lib/backend/backend.py new file mode 100644 index 0000000..95e425d --- /dev/null +++ b/ai_friend/lib/backend/backend.py @@ -0,0 +1,51 @@ +from fastapi import FastAPI, HTTPException +from pymongo import MongoClient +import openai +import firebase_admin +from firebase_admin import credentials, auth + +# Initialize Firebase Admin SDK +cred = credentials.Certificate("path/to/firebase_credentials.json") +firebase_admin.initialize_app(cred) + +# Connect to MongoDB +client = MongoClient("mongodb+srv://wangdaiyu532:@cluster0.kk66p.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0") +db = client["chatbotDB"] +users_collection = db["users"] + +# OpenAI API Key +openai.api_key = "your_openai_api_key" + +app = FastAPI() + +@app.post("/register_user/") +async def register_user(user_data: dict): + """Stores user preferences in MongoDB""" + existing_user = users_collection.find_one({"uid": user_data["uid"]}) + if existing_user: + return {"message": "User already exists"} + + users_collection.insert_one(user_data) + return {"message": "User registered successfully"} + +@app.post("/chat/") +async def chat(user_id: str, message: str): + """Processes user message and returns chatbot response""" + user_data = users_collection.find_one({"uid": user_id}) + if not user_data: + raise HTTPException(status_code=404, detail="User not found") + + # Customizing AI response based on user preference + user_info = f"User is {user_data['age']} years old, prefers {user_data['movie_preference']} movies, enjoys {user_data['hobbies']}." + prompt = f"{user_info} The user says: {message}. How should I respond?" + + response = openai.ChatCompletion.create( + model="gpt-4-turbo", + messages=[{"role": "system", "content": "You are a friendly and emotionally supportive chatbot."}, + {"role": "user", "content": prompt}] + ) + + return {"response": response["choices"][0]["message"]["content"]} + +# Run the server with: +# uvicorn backend:app --host 0.0.0.0 --port 8000 --reload diff --git a/ai_friend/lib/backend/collect_data.dart b/ai_friend/lib/backend/collect_data.dart new file mode 100644 index 0000000..595a98d --- /dev/null +++ b/ai_friend/lib/backend/collect_data.dart @@ -0,0 +1,53 @@ +class UserData { + final String name; + final int age; + final String pronouns; + final String movieType; + final String freeTime; + final String aiName; + final String aiGender; + final String email; + final String password; + + UserData({ + required this.name, + required this.age, + required this.pronouns, + required this.movieType, + required this.freeTime, + required this.aiName, + required this.aiGender, + this.email = '', // Default empty string + this.password = '', // Default empty string + }); + + // Convert object to JSON + Map toJson() { + return { + 'name': name, + 'age': age, + 'pronouns': pronouns, + 'movieType': movieType, + 'freeTime': freeTime, + 'aiName': aiName, + 'aiGender': aiGender, + 'email': email, // Included in JSON output + 'password': password, // Included in JSON output + }; + } + + // Create from JSON + factory UserData.fromJson(Map json) { + return UserData( + name: json['name'] ?? '', + age: json['age'] ?? 0, + pronouns: json['pronouns'] ?? '', + movieType: json['movieType'] ?? '', + freeTime: json['freeTime'] ?? '', + aiName: json['aiName'] ?? '', + aiGender: json['aiGender'] ?? '', + email: json['email'] ?? '', // Default empty if missing + password: json['password'] ?? '', // Default empty if missing + ); + } +} diff --git a/ai_friend/lib/chatscreen.dart b/ai_friend/lib/chatscreen.dart new file mode 100644 index 0000000..cb9b064 --- /dev/null +++ b/ai_friend/lib/chatscreen.dart @@ -0,0 +1,90 @@ +import 'package:ai_friend/diary.dart'; +import 'package:flutter/material.dart'; + +void main() { + runApp(const MaterialApp( + home: ChatScreen(), + )); +} + +class ChatScreen extends StatelessWidget { + const ChatScreen({super.key}); + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + width: double.infinity, + height: double.infinity, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Colors.black87, + Color.fromARGB(255, 28, 20, 151), + ], + ), + ), + child: Stack( + children: [ + Positioned( + top: 40, + left: 20, + child: IconButton( + icon: Icon(Icons.book, color: Colors.white), + onPressed: () { + print("Book icon pressed"); + Navigator.of(context).push( + MaterialPageRoute(builder: (context) => DiaryScreen()), + ); + }, + ), + ), + Positioned( + top: 40, + right: 20, + child: IconButton( + icon: Icon(Icons.settings, color: Colors.white), + onPressed: () { + print("Settings icon pressed"); + }, + ), + ), + Align( + alignment: Alignment.bottomCenter, + child: Padding( + padding: const EdgeInsets.all(20.0), + child: SizedBox( + width: double.infinity, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: Colors.black, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + padding: const EdgeInsets.symmetric(vertical: 15.0), + ), + onPressed: () { + print("Talk to me button pressed"); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Talk to me", + style: TextStyle(color: Colors.white), + ), + SizedBox(width: 5), + Icon(Icons.add, color: Colors.white), + ], + ), + ), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/ai_friend/lib/diary.dart b/ai_friend/lib/diary.dart new file mode 100644 index 0000000..363139d --- /dev/null +++ b/ai_friend/lib/diary.dart @@ -0,0 +1,104 @@ +import 'package:ai_friend/chatscreen.dart'; +import 'package:flutter/material.dart'; + +class DiaryScreen extends StatelessWidget { + // Add a key parameter to the constructor + DiaryScreen({super.key}); + + final List entries = + List.generate(4, (index) => "I have big plan for this weekend"); + final List dates = List.generate(4, (index) => "3rd March 2024"); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + width: double.infinity, + height: double.infinity, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Colors.deepPurple.shade900, + Colors.deepPurple.shade700, + ], + ), + ), + child: Column( + children: [ + SizedBox(height: 40), + Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: EdgeInsets.only(left: 16), + child: IconButton( + icon: Icon(Icons.chat_bubble, color: Colors.white), + onPressed: () { + print("chat icon pressed"); + Navigator.of(context).push( + MaterialPageRoute(builder: (context) => ChatScreen()), + ); + }, + )), + ), + Text( + "Diary", + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + SizedBox(height: 20), + Expanded( + child: ListView.builder( + padding: EdgeInsets.symmetric(horizontal: 16), + itemCount: entries.length, + itemBuilder: (context, index) { + return Container( + margin: EdgeInsets.only(bottom: 16), + padding: EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.2), + borderRadius: BorderRadius.circular(12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + dates[index], + style: TextStyle( + fontSize: 14, + color: Colors.white70, + ), + ), + SizedBox(height: 4), + Text( + entries[index], + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + SizedBox(height: 8), + Text( + "vhdd nf hfs fhf bhtyfefhw ghf hdh vgdhs shdvhsdusd", + style: TextStyle( + fontSize: 14, + color: Colors.white70, + ), + ), + ], + ), + ); + }, + ), + ), + ], + ), + ), + ); + } +} diff --git a/ai_friend/lib/enter_age.dart b/ai_friend/lib/enter_age.dart new file mode 100644 index 0000000..2abf2af --- /dev/null +++ b/ai_friend/lib/enter_age.dart @@ -0,0 +1,140 @@ +import 'package:ai_friend/pronouns.dart'; +import 'package:flutter/material.dart'; + +void main() { + runApp(const MaterialApp( + home: EnterAgePage(name: 'user'), // Provide a default name for testing + )); +} + +class EnterAgePage extends StatefulWidget { + final String name; + const EnterAgePage({ + super.key, + required this.name, + }); + + @override + State createState() => _EnterAgePageState(); +} + +class _EnterAgePageState extends State { + final TextEditingController ageController = TextEditingController(); + bool isButtonEnabled = false; + + @override + void initState() { + super.initState(); + ageController.addListener(_checkInput); + } + + void _checkInput() { + setState(() { + isButtonEnabled = ageController.text.isNotEmpty; + }); + } + + @override + void dispose() { + ageController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF1C1A3B), + body: SafeArea( + child: Column( + children: [ + const SizedBox(height: 100), + Text( + // the passed name + 'Hello, ${widget.name}!', + textAlign: TextAlign.center, + style: const TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold, + fontFamily: 'PoetsenOne', + ), + ), + const SizedBox(height: 50), + const Align( + alignment: Alignment.center, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 32), + child: Text( + 'We need this information to make your experience more relevant and safe.', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.normal, + fontFamily: 'PoetsenOne', + ), + ), + ), + ), + const SizedBox(height: 100), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 32), + child: TextField( + controller: ageController, + textAlign: TextAlign.center, + style: const TextStyle( + color: Colors.white, + fontSize: 28, + fontFamily: 'PoetsenOne', + ), + decoration: const InputDecoration( + hintText: 'Enter your age', + hintStyle: TextStyle( + color: Color(0xFF6E7191), + fontSize: 28, + fontFamily: 'PoetsenOne', + ), + border: InputBorder.none, + ), + ), + ), + const Spacer(), + SizedBox( + width: 275, + height: 64, + child: ElevatedButton( + onPressed: isButtonEnabled + ? () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => PronounSelectionPage( + name: widget.name, + age: int.parse(ageController.text), + ), + ), + ); + } + : null, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF6E7191), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(40), + ), + ), + child: const Text( + 'Continue', + style: TextStyle( + color: Colors.black, + fontSize: 24, + fontFamily: 'PoetsenOne', + ), + ), + ), + ), + const SizedBox(height: 40), + ], + ), + ), + ); + } +} diff --git a/ai_friend/lib/enter_name.dart b/ai_friend/lib/enter_name.dart new file mode 100644 index 0000000..924c559 --- /dev/null +++ b/ai_friend/lib/enter_name.dart @@ -0,0 +1,120 @@ +import 'package:ai_friend/enter_age.dart'; +import 'package:flutter/material.dart'; + +void main() { + runApp(const MaterialApp( + home: EnterNamePage(), + )); +} + +class EnterNamePage extends StatefulWidget { + const EnterNamePage({super.key}); + + @override + State createState() => _EnterNamePageState(); +} + +class _EnterNamePageState extends State { + final TextEditingController nameController = TextEditingController(); + bool isButtonEnabled = false; + + @override + void initState() { + super.initState(); + nameController.addListener(_checkInput); + } + + void _checkInput() { + setState(() { + isButtonEnabled = nameController.text.isNotEmpty; + }); + } + + @override + void dispose() { + nameController.dispose(); + super.dispose(); + } + + @override + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF1C1A3B), + body: SafeArea( + child: Column( + children: [ + const SizedBox(height: 100), + const Align( + alignment: Alignment.center, + child: Text( + 'Your name', + style: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold, + fontFamily: 'PoetsenOne', + ), + ), + ), + const SizedBox(height: 100), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 32), + child: TextField( + controller: nameController, + textAlign: TextAlign.center, + style: const TextStyle( + color: Colors.white, + fontSize: 28, + fontFamily: 'PoetsenOne', + ), + decoration: const InputDecoration( + hintText: 'Enter your name', + hintStyle: TextStyle( + color: Color(0xFF6E7191), + fontSize: 28, + fontFamily: 'PoetsenOne', + ), + border: InputBorder.none, + ), + ), + ), + const Spacer(), + SizedBox( + width: 275, + height: 64, + child: ElevatedButton( + onPressed: isButtonEnabled + ? () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => EnterAgePage( + name: nameController.text.trim(), // pass name + ), + ), + ); + } + : null, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF6E7191), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(40), + ), + ), + child: const Text( + 'Continue', + style: TextStyle( + color: Colors.black, + fontSize: 24, + fontFamily: 'PoetsenOne', + ), + ), + ), + ), + const SizedBox(height: 40), + ], + ), + ), + ); + } +} diff --git a/ai_friend/lib/free_time.dart b/ai_friend/lib/free_time.dart new file mode 100644 index 0000000..07f90aa --- /dev/null +++ b/ai_friend/lib/free_time.dart @@ -0,0 +1,142 @@ +import 'package:ai_friend/movie_type.dart'; +import 'package:flutter/material.dart'; + +class FreeTimePage extends StatefulWidget { + final String name; + final int age; + final String pronouns; + + const FreeTimePage({ + super.key, + required this.name, + required this.age, + required this.pronouns, + }); + + @override + State createState() => _FreeTimePageState(); +} + +class _FreeTimePageState extends State { + int? selectedIndex; + bool isButtonEnabled = false; + + final List> freeTimeOptions = [ + {"text": "Enjoying being alone", "image": "assets/images/reading.png"}, + {"text": "With friends and family", "image": "assets/images/friends.png"}, + {"text": "Engaging in hobbies", "image": "assets/images/watercolor.jpg"}, + {"text": "Partying/socializing", "image": "assets/images/men.jpg"}, + {"text": "Staying productive", "image": "assets/images/working.jpg"}, + ]; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF1C1A3B), // Consistent dark background + body: SafeArea( + child: Column( + children: [ + const SizedBox(height: 40), + Align( + alignment: Alignment.centerLeft, + child: IconButton( + icon: const Icon(Icons.arrow_back, color: Colors.white), + onPressed: () => Navigator.pop(context), + ), + ), + const SizedBox(height: 40), + const Align( + alignment: Alignment.center, + child: Text( + 'How do you usually\nspend your free time?', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold, + fontFamily: 'PoetsenOne', + ), + ), + ), + const SizedBox(height: 50), + Expanded( + child: ListView.builder( + padding: const EdgeInsets.symmetric(horizontal: 32), + itemCount: freeTimeOptions.length, + itemBuilder: (context, index) { + bool isSelected = selectedIndex == index; + return Padding( + padding: const EdgeInsets.only(bottom: 16), + child: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: + isSelected ? Colors.blue : const Color(0xFF6E7191), + foregroundColor: Colors.white, + minimumSize: const Size(double.infinity, 80), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + padding: const EdgeInsets.symmetric(vertical: 20), + ), + onPressed: () { + setState(() { + selectedIndex = index; + isButtonEnabled = true; + }); + }, + child: Text( + freeTimeOptions[index]["text"]!, + style: const TextStyle( + fontSize: 18, + fontFamily: 'PoetsenOne', + ), + ), + ), + ); + }, + ), + ), + const SizedBox(height: 30), + SizedBox( + width: 275, + height: 64, + child: ElevatedButton( + onPressed: isButtonEnabled + ? () { + // Navigate to next screen with all collected data + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => MovieTypePage( + name: widget.name, + age: widget.age, + pronouns: widget.pronouns, + freeTime: freeTimeOptions[selectedIndex!] + ["text"]!, + ), + ), + ); + } + : null, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF6E7191), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(40), + ), + ), + child: const Text( + 'Continue', + style: TextStyle( + color: Colors.black, + fontSize: 24, + fontFamily: 'PoetsenOne', + ), + ), + ), + ), + const SizedBox(height: 40), + ], + ), + ), + ); + } +} diff --git a/ai_friend/lib/loading.dart b/ai_friend/lib/loading.dart new file mode 100644 index 0000000..789fd44 --- /dev/null +++ b/ai_friend/lib/loading.dart @@ -0,0 +1,52 @@ +import 'package:flutter/material.dart'; + +void main() { + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: LoadingScreen(), + ); + } +} + +class LoadingScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + width: double.infinity, + height: double.infinity, + decoration: BoxDecoration( + color: Color(0xFF141233), + ), + child: Stack( + children: [ + Positioned( + top: 60, + left: MediaQuery.of(context).size.width * 0.25, + child: Image.asset( + 'assets/images/hhhhj.png', + width: 150, + ), + ), + Align( + alignment: Alignment.bottomCenter, + child: Padding( + padding: const EdgeInsets.only(bottom: 100.0), + child: Image.asset( + 'assets/images/Group.png', + width: 150, + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/ai_friend/lib/login_componments/func.dart b/ai_friend/lib/login_componments/func.dart new file mode 100644 index 0000000..e69de29 diff --git a/ai_friend/lib/login_componments/log_button.dart b/ai_friend/lib/login_componments/log_button.dart new file mode 100644 index 0000000..5e50685 --- /dev/null +++ b/ai_friend/lib/login_componments/log_button.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; + +class SigninBtn extends StatelessWidget { + final Function()? onTap; + const SigninBtn({super.key, required this.onTap}); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + margin: EdgeInsets.symmetric(horizontal: 10.0), + padding: EdgeInsets.symmetric(vertical: 25), + decoration: BoxDecoration( + color: const Color.fromARGB(255, 0, 0, 0), + borderRadius: BorderRadius.circular(10), + ), + + child: const Center( + child: Text( + "Sign In", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w500, + fontSize: 20, + ), + + ), + ), + ), + ); + } +} + diff --git a/ai_friend/lib/login_componments/log_forgot_password.dart b/ai_friend/lib/login_componments/log_forgot_password.dart new file mode 100644 index 0000000..d84f01d --- /dev/null +++ b/ai_friend/lib/login_componments/log_forgot_password.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; + +class LoginForgotPassword extends StatelessWidget { + + final Function()? onTapp; + const LoginForgotPassword({super.key,required this.onTapp}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(right: 40.0), + child: Row( + mainAxisAlignment: + MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + GestureDetector( + onTap: () { + // Handle forgot password tap here. + // or + showDialog(context: context, builder: (context) => AlertDialog(title: Text("Forgot Password Tapped"), content: Text("Implement your logic here"))); + }, + //forgot password + child: Text( + "Forgot Password?", + style: TextStyle( + color: Color.fromARGB(255, 95, 95, 95), + fontWeight: FontWeight.w500, + fontSize: 18, + decoration: TextDecoration.underline, + decorationColor: Color.fromARGB(255, 95, 95, 95), + decorationStyle: TextDecorationStyle + .solid, + decorationThickness: 2.0, + ), + ), + ), + ]), + ); + } +} + diff --git a/ai_friend/lib/login_componments/log_textfields.dart b/ai_friend/lib/login_componments/log_textfields.dart new file mode 100644 index 0000000..e44c39e --- /dev/null +++ b/ai_friend/lib/login_componments/log_textfields.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; + + + +class LoginTextfield extends StatelessWidget { + final dynamic controllarFor; // what is dynamic , what happnes withouth it? + final String hintText; + final bool obscureText; + final String textBoxName; + + + const LoginTextfield({ + super.key, + required this.controllarFor, + required this.hintText, + required this.obscureText, + required this.textBoxName, + }); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 15.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // text field name + Text( + textBoxName, + style: TextStyle( + color: Colors.white70, + fontSize: 16.0, + fontWeight: FontWeight.w500, + ), + ), + // text feild + TextField( + style: const TextStyle(color: Color.fromARGB(255, 1, 0, 0), fontSize: 20), + controller: controllarFor, + obscureText: obscureText, + decoration: InputDecoration( + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color.fromARGB(67, 255, 255, 255), width: 3.0), + borderRadius: BorderRadius.circular(12.0), + ), + + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xFF303841),), + borderRadius: BorderRadius.circular(12.0), + ), + + fillColor: Color.fromARGB(255, 255, 255, 255), + filled: true, + hintText: hintText, + hintStyle: TextStyle( + color: const Color.fromARGB(255, 135, 133, 133), + fontSize: 16, + + ) + ), + ), + ], + ), + ); + } +} // login page text feilds for email and password diff --git a/ai_friend/lib/main.dart b/ai_friend/lib/main.dart index 8e94089..bffb398 100644 --- a/ai_friend/lib/main.dart +++ b/ai_friend/lib/main.dart @@ -1,125 +1,24 @@ +import 'package:ai_friend/chatscreen.dart'; import 'package:flutter/material.dart'; +import 'package:firebase_core/firebase_core.dart'; +//import 'dart:convert'; +//import 'package:http/http.dart' as http; -void main() { - runApp(const MyApp()); +//flutter run -t lib/enter_name.dart + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp(); + runApp(MyApp()); // Wrap in MyApp } class MyApp extends StatelessWidget { - const MyApp({super.key}); - - // This widget is the root of your application. + MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // TRY THIS: Try running your application with "flutter run". You'll see - // the application has a purple toolbar. Then, without quitting the app, - // try changing the seedColor in the colorScheme below to Colors.green - // and then invoke "hot reload" (save your changes or press the "hot - // reload" button in a Flutter-supported IDE, or press "r" if you used - // the command line to start the app). - // - // Notice that the counter didn't reset back to zero; the application - // state is not lost during the reload. To reset the state, use hot - // restart instead. - // - // This works for code too, not just values: Most code changes can be - // tested with just a hot reload. - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - useMaterial3: true, - ), - home: const MyHomePage(title: 'Flutter Demo Home Page'), - ); - } -} - -class MyHomePage extends StatefulWidget { - const MyHomePage({super.key, required this.title}); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - State createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - appBar: AppBar( - // TRY THIS: Try changing the color here to a specific color (to - // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar - // change color while the other colors stay the same. - backgroundColor: Theme.of(context).colorScheme.inversePrimary, - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - // - // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" - // action in the IDE, or press "p" in the console), to see the - // wireframe for each widget. - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. + debugShowCheckedModeBanner: false, + home: ChatScreen(), // Set ChatScreen as the home ); } } diff --git a/ai_friend/lib/movie_type.dart b/ai_friend/lib/movie_type.dart new file mode 100644 index 0000000..559c98d --- /dev/null +++ b/ai_friend/lib/movie_type.dart @@ -0,0 +1,144 @@ +import 'package:ai_friend/ai_gender.dart'; +import 'package:flutter/material.dart'; + +class MovieTypePage extends StatefulWidget { + final String name; + final int age; + final String pronouns; + final String freeTime; + + const MovieTypePage({ + super.key, + required this.name, + required this.age, + required this.pronouns, + required this.freeTime, + }); + + @override + State createState() => _MovieTypePageState(); +} + +class _MovieTypePageState extends State { + int? selectedIndex; + bool isButtonEnabled = false; + + final List> movieOptions = [ + {"text": "Action/Adventure", "image": "assets/action.jpg"}, + {"text": "Drama/Romance", "image": "assets/drama.jpg"}, + {"text": "Comedy", "image": "assets/comedy.jpg"}, + {"text": "Science Fiction/Fantasy", "image": "assets/scifi.jpg"}, + {"text": "Horror/Thriller", "image": "assets/horror.jpg"}, + ]; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF1C1A3B), // Consistent dark background + body: SafeArea( + child: Column( + children: [ + const SizedBox(height: 40), + Align( + alignment: Alignment.centerLeft, + child: IconButton( + icon: const Icon(Icons.arrow_back, color: Colors.white), + onPressed: () => Navigator.pop(context), + ), + ), + const SizedBox(height: 40), + const Align( + alignment: Alignment.center, + child: Text( + 'What is your favorite\nmovie type?', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold, + fontFamily: 'PoetsenOne', + ), + ), + ), + const SizedBox(height: 50), + Expanded( + child: ListView.builder( + padding: const EdgeInsets.symmetric(horizontal: 32), + itemCount: movieOptions.length, + itemBuilder: (context, index) { + bool isSelected = selectedIndex == index; + return Padding( + padding: const EdgeInsets.only(bottom: 16), + child: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: + isSelected ? Colors.blue : const Color(0xFF6E7191), + foregroundColor: Colors.white, + minimumSize: const Size(double.infinity, 80), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + padding: const EdgeInsets.symmetric(vertical: 20), + ), + onPressed: () { + setState(() { + selectedIndex = index; + isButtonEnabled = true; + }); + }, + child: Text( + movieOptions[index]["text"]!, + style: const TextStyle( + fontSize: 18, + fontFamily: 'PoetsenOne', + ), + ), + ), + ); + }, + ), + ), + const SizedBox(height: 30), + SizedBox( + width: 275, + height: 64, + child: ElevatedButton( + onPressed: isButtonEnabled + ? () { + // Navigate to next screen with all collected data + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => GenderSelectionPage( + name: widget.name, + age: widget.age, + pronouns: widget.pronouns, + freeTime: widget.freeTime, + movieType: movieOptions[selectedIndex!]["text"]!, + ), + ), + ); + } + : null, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF6E7191), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(40), + ), + ), + child: const Text( + 'Continue', + style: TextStyle( + color: Colors.black, + fontSize: 24, + fontFamily: 'PoetsenOne', + ), + ), + ), + ), + const SizedBox(height: 40), + ], + ), + ), + ); + } +} diff --git a/ai_friend/lib/pages/login_page.dart b/ai_friend/lib/pages/login_page.dart new file mode 100644 index 0000000..7493d7a --- /dev/null +++ b/ai_friend/lib/pages/login_page.dart @@ -0,0 +1,116 @@ +import 'package:flutter/material.dart'; +import '../login_componments/log_textfields.dart'; +import '../login_componments/log_button.dart'; +import '../login_componments/log_forgot_password.dart'; + +void main() { + runApp(LoginPage()); +} + +class LoginPage extends StatelessWidget { + LoginPage({super.key}); + // ----------------------------------------functions----------- + // text editing controllers + final emailController = TextEditingController(); + final passwordController = TextEditingController(); + + // Validation Function ------- + bool _validateInput() { + String email = emailController.text; // email text fields + String password = passwordController.text; // passowrd + // validation + if (email.isEmpty || !isValidEmail(email)) { + return false; + } + + if (password.isEmpty || password.length < 8 || password.length > 20) { + return false; + } + return true; + } + +// Email Validation Fun (later use a package like email_validator) + bool isValidEmail(String email) { + final emailRegExp = RegExp( + r"^[a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"); // Regular expression + return emailRegExp.hasMatch(email); + } + + // sing in user method + Future signUserIn(BuildContext context) async { + // Simulate a successful login (replace with actual logic later) + + await Future.delayed(const Duration(seconds: 1)); // a delay + + // singin message + debugPrint("Message:---Sign in--> next page"); + } + + void forgotPass() { + // content + } + //-------------------------------UI start from here-------- + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Color.fromARGB(255, 13, 21, 31), + // appbar here... + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Center( + child: SingleChildScrollView( + // Scroll only the content within the Center + child: Container( + constraints: BoxConstraints(maxWidth: 400), + child: Column( + children: [ + SizedBox(height: 50), + + LoginTextfield( + controllarFor: emailController, + hintText: 'Enter Your Email', + obscureText: false, + textBoxName: 'Email:', + ), // Email + + SizedBox(height: 5), + + LoginTextfield( + controllarFor: passwordController, + hintText: 'Enter Your Password', + obscureText: true, + textBoxName: 'Password:', + ), // password + + SizedBox(height: 13), + + LoginForgotPassword(onTapp: forgotPass), + + SizedBox(height: 50), + + SigninBtn( + onTap: () async { + // Perform Validation + if (_validateInput()) { + signUserIn(context); + } else { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Invalid email or password'), + ), // Error Message + ); + } + }, + ), + SizedBox(height: 20), + ], + ), + ), + ), + ), + ), + ), + ); + } +} diff --git a/ai_friend/lib/pages/test1.dart b/ai_friend/lib/pages/test1.dart new file mode 100644 index 0000000..062f3c3 --- /dev/null +++ b/ai_friend/lib/pages/test1.dart @@ -0,0 +1,32 @@ +import 'package:flutter/material.dart'; + +class Log extends StatelessWidget { + const Log({super.key}); + + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor:Color.fromARGB(255, 13, 21, 31) , + // appbar here + appBar: AppBar( + + backgroundColor: Color.fromARGB(211, 7, 82, 73), + title: const Text( + 'Login', + style: TextStyle( + color: Color.fromARGB(255, 255, 255, 255), + fontSize: 25, + ), + ), + automaticallyImplyLeading: false, // The title of the app bar + ), + body: SafeArea( + child:Center( + child: +Text("you are now in forgotpass page"), + ) + ), + ); + } +} \ No newline at end of file diff --git a/ai_friend/lib/pronouns.dart b/ai_friend/lib/pronouns.dart new file mode 100644 index 0000000..7699ae2 --- /dev/null +++ b/ai_friend/lib/pronouns.dart @@ -0,0 +1,134 @@ +import 'package:ai_friend/free_time.dart'; +import 'package:flutter/material.dart'; +//import 'package:ai_friend/select_movie.dart'; // Import your SelectMoviePage + +class PronounSelectionPage extends StatefulWidget { + final String name; + final int age; + + const PronounSelectionPage({ + super.key, + required this.name, + required this.age, + }); + + @override + State createState() => _PronounSelectionPageState(); +} + +class _PronounSelectionPageState extends State { + String? selectedPronoun; + bool isButtonEnabled = false; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF1C1A3B), // Dark background + body: SafeArea( + child: Column( + children: [ + const SizedBox(height: 100), // Space from top + const Align( + alignment: Alignment.center, + child: Text( + 'Select Your Pronouns', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold, + fontFamily: 'PoetsenOne', + ), + ), + ), + const SizedBox(height: 50), // Space before additional text + const Align( + alignment: Alignment.center, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 32), + child: Text( + 'We need this information to make your experience more relevant and safe.', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.normal, + fontFamily: 'PoetsenOne', + ), + ), + ), + ), + const SizedBox(height: 60), // Space before buttons + _buildPronounButton("She / Her"), + _buildPronounButton("He / Him"), + _buildPronounButton("They / Them"), + const Spacer(), // Push button to bottom + SizedBox( + width: 275, // Button width + height: 64, // Button height + child: ElevatedButton( + onPressed: isButtonEnabled + ? () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => FreeTimePage( + name: widget.name, + age: widget.age, + pronouns: selectedPronoun!, + ), + ), + ); + } + : null, // Disabled if no pronoun selected + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF6E7191), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(40), + ), + ), + child: const Text( + 'Continue', + style: TextStyle( + color: Colors.black, + fontSize: 24, + fontFamily: 'PoetsenOne', + ), + ), + ), + ), + const SizedBox(height: 40), // Bottom spacing + ], + ), + ), + ); + } + + Widget _buildPronounButton(String pronoun) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 32), + child: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: selectedPronoun == pronoun + ? Colors.blue + : const Color(0xFF6E7191), + foregroundColor: + selectedPronoun == pronoun ? Colors.white : Colors.black, + minimumSize: const Size(double.infinity, 50), + ), + onPressed: () { + setState(() { + selectedPronoun = pronoun; + isButtonEnabled = true; + }); + }, + child: Text( + pronoun, + style: const TextStyle( + fontSize: 18, + fontFamily: 'PoetsenOne', + ), + ), + ), + ); + } +} diff --git a/ai_friend/lib/signup.dart b/ai_friend/lib/signup.dart new file mode 100644 index 0000000..f10dffd --- /dev/null +++ b/ai_friend/lib/signup.dart @@ -0,0 +1,256 @@ +import 'package:flutter/material.dart'; + +class SignUpScreen extends StatefulWidget { + const SignUpScreen({super.key}); + + @override + // ignore: library_private_types_in_public_api + _SignUpScreenState createState() => _SignUpScreenState(); +} + +class _SignUpScreenState extends State { + // Initial color for the login link + Color loginLinkColor = Colors.white; + + // Initial color for the create account button + Color createAccountButtonColor = const Color.fromARGB(255, 87, 105, 143); + + // Controller for the email TextField + final TextEditingController _emailController = TextEditingController(); + + // Form key for validation + final GlobalKey _formKey = GlobalKey(); + + // Email validation function + String? _validateEmail(String? value) { + if (value == null || value.isEmpty) { + return 'Please enter your email'; + } + // Regular expression for email validation + final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$'); + if (!emailRegex.hasMatch(value)) { + return 'Please enter a valid email'; + } + return null; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color.fromARGB(221, 6, 3, 56), + body: Center( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Form( + key: _formKey, // Assign the form key + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const CircleAvatar( + radius: 40, + backgroundColor: Colors.grey, + ), + const SizedBox(height: 50), + const Text( + 'Create an account', + style: TextStyle( + fontSize: 30, + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 20), + RichText( + text: TextSpan( + text: "Already have an account? ", + style: const TextStyle(color: Colors.white, fontSize: 16), + children: [ + WidgetSpan( + child: MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + onTap: () { + setState(() { + loginLinkColor = + const Color.fromARGB(255, 24, 169, 195); + }); + + Future.delayed(const Duration(seconds: 1), () { + setState(() { + loginLinkColor = Colors.white; + }); + }); + }, + child: Text( + "Log in", + style: TextStyle( + decoration: TextDecoration.underline, + decorationColor: loginLinkColor, + color: loginLinkColor, + fontSize: 16, + fontWeight: FontWeight.w600, + fontFamily: 'Roboto', + ), + ), + ), + ), + ), + ], + ), + ), + const SizedBox(height: 50), + + // Continue with Facebook Button + ElevatedButton.icon( + style: ElevatedButton.styleFrom( + backgroundColor: Colors.white, + foregroundColor: Colors.black, + minimumSize: const Size(350, 60), + ), + icon: Image.asset( + 'assets/images/fb.png', // Path to your Facebook icon + width: 30, + height: 30, + ), + label: const Text( + 'Continue with Facebook', + style: TextStyle(fontSize: 18), + ), + onPressed: () {}, + ), + const SizedBox(height: 10), + + // Continue with Google Button + ElevatedButton.icon( + style: ElevatedButton.styleFrom( + backgroundColor: Colors.white, + foregroundColor: Colors.black, + minimumSize: const Size(350, 60), + ), + icon: Image.asset( + 'assets/images/google.png', // Path to your Google icon + width: 28, + height: 28, + ), + label: const Text( + 'Continue with Google', + style: TextStyle(fontSize: 18), + ), + onPressed: () {}, + ), + + const SizedBox(height: 20), + Row( + children: const [ + Expanded( + child: Divider( + color: Colors.white, + thickness: 1, + height: 20, + ), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 10), + child: Text( + 'OR', + style: TextStyle(color: Colors.white), + ), + ), + Expanded( + child: Divider( + color: Colors.white, + thickness: 1, + height: 20, + ), + ), + ], + ), + const SizedBox(height: 20), + const Text( + 'Enter your email address to create the account', + style: TextStyle(color: Colors.white, fontSize: 16), + ), + const SizedBox(height: 10), + + // Email TextFormField with Validation + SizedBox( + width: 550, // Set the desired width here + child: TextFormField( + controller: _emailController, + decoration: InputDecoration( + hintText: 'Your email', + hintStyle: const TextStyle(color: Colors.white), + prefixIcon: const Icon(Icons.email, color: Colors.white), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8), + borderSide: BorderSide.none, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(8), + borderSide: BorderSide( + color: Colors.grey.shade300, + width: 1.0, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(8), + borderSide: const BorderSide( + color: Colors.blue, + width: 2.0, + ), + ), + errorStyle: const TextStyle( + color: Colors.red), // Error text color + ), + style: const TextStyle(color: Colors.white), + keyboardType: TextInputType.emailAddress, + validator: _validateEmail, // Add validation + ), + ), + + const SizedBox(height: 30), + + // Create an Account Button + ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: createAccountButtonColor, + foregroundColor: Colors.white, + minimumSize: const Size(300, 60), + ), + onPressed: () { + // Validate the form + if (_formKey.currentState!.validate()) { + // If the form is valid, proceed + // ignore: avoid_print + print('Email is valid: ${_emailController.text}'); + setState(() { + createAccountButtonColor = + const Color.fromARGB(255, 40, 144, 255); + }); + + Future.delayed(const Duration(seconds: 1), () { + setState(() { + createAccountButtonColor = + const Color.fromARGB(255, 62, 119, 241); + }); + }); + } + }, + child: const Text( + 'Create an account', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + fontFamily: 'Roboto', + color: Color.fromARGB(255, 1, 15, 55), + ), + ), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/ai_friend/lib/start-5.dart b/ai_friend/lib/start-5.dart deleted file mode 100644 index c7ba577..0000000 --- a/ai_friend/lib/start-5.dart +++ /dev/null @@ -1,113 +0,0 @@ -import 'package:flutter/material.dart'; - -class MovieTypeScreen extends StatefulWidget { - @override - _MovieTypeScreenState createState() => _MovieTypeScreenState(); -} - -class _MovieTypeScreenState extends State { - int? selectedIndex; - - final List> movieOptions = [ - {"text": "Action/ Adventure", "image": "assets/action.jpg"}, - {"text": "Drama/ Romance", "image": "assets/drama.jpg"}, - {"text": "Comedy", "image": "assets/comedy.jpg"}, - {"text": "Science fiction/ Fantasy", "image": "assets/scifi.jpg"}, - {"text": "Horror/ Thriller", "image": "assets/horror.jpg"}, - ]; - - void onSelect(int index) { - setState(() { - selectedIndex = index; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Colors.deepPurple[900], - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 40), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - GestureDetector( - onTap: () { - Navigator.pop(context); - }, - child: Icon(Icons.arrow_back, color: Colors.white, size: 30), - ), - SizedBox(height: 20), - Center( - child: Text( - "What is your favorite movie type?", - textAlign: TextAlign.center, - style: TextStyle( - color: Colors.white, - fontSize: 18, - fontWeight: FontWeight.bold, - ), - ), - ), - SizedBox(height: 20), - Expanded( - child: ListView.builder( - itemCount: movieOptions.length, - itemBuilder: (context, index) { - bool isSelected = selectedIndex == index; - return GestureDetector( - onTap: () => onSelect(index), - child: Container( - margin: EdgeInsets.symmetric(vertical: 8), - padding: EdgeInsets.symmetric(vertical: 15, horizontal: 20), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(25), - border: Border.all(color: Colors.white), - image: DecorationImage( - image: AssetImage(movieOptions[index]["image"]!), - fit: BoxFit.cover, - colorFilter: ColorFilter.mode( - Colors.black.withOpacity(isSelected ? 0.4 : 0.7), - BlendMode.darken, - ), - ), - ), - child: Center( - child: Text( - movieOptions[index]["text"]!, - style: TextStyle( - color: Colors.white, - fontSize: 16, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - ); - }, - ), - ), - SizedBox(height: 20), - GestureDetector( - onTap: selectedIndex != null ? () {} : null, - child: Container( - width: double.infinity, - padding: EdgeInsets.symmetric(vertical: 15), - decoration: BoxDecoration( - color: selectedIndex != null ? Colors.blue : Colors.grey, - borderRadius: BorderRadius.circular(25), - ), - child: Center( - child: Text( - "Continue", - style: TextStyle(color: Colors.white, fontSize: 18), - ), - ), - ), - ), - ], - ), - ), - ); - } -} diff --git a/ai_friend/lib/start-1.dart b/ai_friend/lib/start1.dart similarity index 63% rename from ai_friend/lib/start-1.dart rename to ai_friend/lib/start1.dart index c415b43..3e11eb4 100644 --- a/ai_friend/lib/start-1.dart +++ b/ai_friend/lib/start1.dart @@ -1,20 +1,23 @@ +import 'package:ai_friend/start2.dart'; import 'package:flutter/material.dart'; void main() { - runApp(Start_1()); + runApp(const EnterName()); } -class Start_1 extends StatelessWidget { +class EnterName extends StatelessWidget { + const EnterName({super.key}); + @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( - backgroundColor: Color(0xFF1C1A3B), + backgroundColor: const Color(0xFF1C1A3B), body: SafeArea( child: Column( children: [ - SizedBox(height: 109), // Position "Your Name" text - Align( + const SizedBox(height: 109), + const Align( alignment: Alignment.center, child: Text( 'Your name', @@ -23,67 +26,69 @@ class Start_1 extends StatelessWidget { color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold, - fontFamily: 'PoetsenOne', + fontFamily: 'PoetsenOne', // Ensure this is correct ), ), ), - SizedBox(height: 100), // Space before TextField - Padding( + const SizedBox(height: 100), + const Padding( padding: EdgeInsets.symmetric(horizontal: 32), child: TextField( textAlign: TextAlign.center, style: TextStyle( color: Colors.white, fontSize: 32, - fontFamily: 'poetsenOne', + fontFamily: 'PoetsenOne', // Ensure this is correct ), decoration: InputDecoration( hintText: 'Enter your name', hintStyle: TextStyle( color: Color(0xFF6E7191), fontSize: 32, - fontFamily: 'ponnala', + fontFamily: 'PoetsenOne', // Ensure this is correct ), - border: InputBorder.none, // Remove underline + border: InputBorder.none, ), ), ), - Expanded(child: SizedBox()), // Pushes button to the bottom + const Spacer(), // Pushes button to the bottom SizedBox( - width: 275, // Set button width - height: 64, // Set button height + width: 275, + height: 64, child: ElevatedButton( onPressed: () { - debugPrint("Continue Button Pressed"); + print("next page"); + Navigator.of(context).push( + MaterialPageRoute(builder: (context) => SelectAge()), + ); }, style: ButtonStyle( backgroundColor: MaterialStateProperty.resolveWith( (Set states) { if (states.contains(MaterialState.pressed)) { - return Colors - .white; // Button turns white when pressed + return Colors.white; } - return Color(0xFF6E7191); // Default color of button + return const Color(0xFF6E7191); }, ), - shape: MaterialStateProperty.all( + shape: MaterialStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(40), ), ), ), - child: Text( + child: const Text( 'Continue', style: TextStyle( color: Colors.black, fontSize: 24, fontWeight: FontWeight.normal, - fontFamily: 'poetsenOne', + fontFamily: 'PoetsenOne', ), ), ), ), - SizedBox(height: 40), // Space from bottom + const SizedBox(height: 40), ], ), ), diff --git a/ai_friend/lib/start-2.dart b/ai_friend/lib/start2.dart similarity index 92% rename from ai_friend/lib/start-2.dart rename to ai_friend/lib/start2.dart index 8777021..2c4495b 100644 --- a/ai_friend/lib/start-2.dart +++ b/ai_friend/lib/start2.dart @@ -1,11 +1,8 @@ +import 'package:ai_friend/enter_name.dart'; import 'package:flutter/material.dart'; -void main() { - runApp(const Start1()); -} - -class Start1 extends StatelessWidget { - const Start1({super.key}); +class SelectAge extends StatelessWidget { + const SelectAge({super.key}); @override Widget build(BuildContext context) { @@ -73,7 +70,10 @@ class Start1 extends StatelessWidget { height: 64, // Button height child: ElevatedButton( onPressed: () { - debugPrint("Continue Button Pressed"); + print("next page"); + Navigator.of(context).push( + MaterialPageRoute(builder: (context) => EnterNamePage()), + ); }, style: ButtonStyle( backgroundColor: MaterialStateProperty.resolveWith( diff --git a/ai_friend/macos/Flutter/GeneratedPluginRegistrant.swift b/ai_friend/macos/Flutter/GeneratedPluginRegistrant.swift index cccf817..1102414 100644 --- a/ai_friend/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/ai_friend/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,6 +5,10 @@ import FlutterMacOS import Foundation +import cloud_firestore +import firebase_core func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin")) + FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) } diff --git a/ai_friend/macos/Flutter/ephemeral/Flutter-Generated.xcconfig b/ai_friend/macos/Flutter/ephemeral/Flutter-Generated.xcconfig deleted file mode 100644 index aee4868..0000000 --- a/ai_friend/macos/Flutter/ephemeral/Flutter-Generated.xcconfig +++ /dev/null @@ -1,11 +0,0 @@ -// This is a generated file; do not edit or check into version control. -FLUTTER_ROOT=C:\src\flutter_windows_3.10.5-stable\flutter -FLUTTER_APPLICATION_PATH=C:\Users\USER\Documents\GitHub\Computing-Group-Project\ai_friend -COCOAPODS_PARALLEL_CODE_SIGN=true -FLUTTER_BUILD_DIR=build -FLUTTER_BUILD_NAME=1.0.0 -FLUTTER_BUILD_NUMBER=1 -DART_OBFUSCATION=false -TRACK_WIDGET_CREATION=true -TREE_SHAKE_ICONS=false -PACKAGE_CONFIG=.dart_tool/package_config.json diff --git a/ai_friend/macos/Flutter/ephemeral/flutter_export_environment.sh b/ai_friend/macos/Flutter/ephemeral/flutter_export_environment.sh deleted file mode 100644 index 5b90864..0000000 --- a/ai_friend/macos/Flutter/ephemeral/flutter_export_environment.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -# This is a generated file; do not edit or check into version control. -export "FLUTTER_ROOT=C:\src\flutter_windows_3.10.5-stable\flutter" -export "FLUTTER_APPLICATION_PATH=C:\Users\USER\Documents\GitHub\Computing-Group-Project\ai_friend" -export "COCOAPODS_PARALLEL_CODE_SIGN=true" -export "FLUTTER_BUILD_DIR=build" -export "FLUTTER_BUILD_NAME=1.0.0" -export "FLUTTER_BUILD_NUMBER=1" -export "DART_OBFUSCATION=false" -export "TRACK_WIDGET_CREATION=true" -export "TREE_SHAKE_ICONS=false" -export "PACKAGE_CONFIG=.dart_tool/package_config.json" diff --git a/ai_friend/pubspec.lock b/ai_friend/pubspec.lock index bbde030..71bf06a 100644 --- a/ai_friend/pubspec.lock +++ b/ai_friend/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: "7fd72d77a7487c26faab1d274af23fb008763ddc10800261abbfb2c067f183d5" + url: "https://pub.dev" + source: hosted + version: "1.3.53" async: dependency: transitive description: @@ -33,6 +41,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.2" + cloud_firestore: + dependency: "direct main" + description: + name: cloud_firestore + sha256: "6b5d0ca6b62830ca5bcf98c5e0c882df32dea3cb523b635db3626333e1c29090" + url: "https://pub.dev" + source: hosted + version: "5.6.5" + cloud_firestore_platform_interface: + dependency: transitive + description: + name: cloud_firestore_platform_interface + sha256: "149c7d2d634178aff8e25eba6cbbbc76bd92f37e0e63727a31952c72bbcb77fb" + url: "https://pub.dev" + source: hosted + version: "6.6.5" + cloud_firestore_web: + dependency: transitive + description: + name: cloud_firestore_web + sha256: "05a3c02a7edb3fadeb3f14f491c3a0bbad3ea2c9f22842acbf1d73bceeb93e77" + url: "https://pub.dev" + source: hosted + version: "4.4.5" collection: dependency: transitive description: @@ -57,6 +89,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.2" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + sha256: f4d8f49574a4e396f34567f3eec4d38ab9c3910818dec22ca42b2a467c685d8b + url: "https://pub.dev" + source: hosted + version: "3.12.1" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: d7253d255ff10f85cfd2adaba9ac17bae878fa3ba577462451163bd9f1d1f0bf + url: "https://pub.dev" + source: hosted + version: "5.4.0" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: faa5a76f6380a9b90b53bc3bdcb85bc7926a382e0709b9b5edac9f7746651493 + url: "https://pub.dev" + source: hosted + version: "2.21.1" flutter: dependency: "direct main" description: flutter @@ -75,6 +131,27 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + http: + dependency: "direct main" + description: + name: http + sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f + url: "https://pub.dev" + source: hosted + version: "1.3.0" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" leak_tracker: dependency: transitive description: @@ -139,6 +216,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.1" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" sky_engine: dependency: transitive description: flutter @@ -192,6 +277,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.4" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" vector_math: dependency: transitive description: @@ -208,6 +301,14 @@ packages: url: "https://pub.dev" source: hosted version: "14.3.1" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.dev" + source: hosted + version: "1.1.1" sdks: dart: ">=3.7.0-0 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" + flutter: ">=3.22.0" diff --git a/ai_friend/pubspec.yaml b/ai_friend/pubspec.yaml index dbe7470..068d5f3 100644 --- a/ai_friend/pubspec.yaml +++ b/ai_friend/pubspec.yaml @@ -30,10 +30,15 @@ environment: dependencies: flutter: sdk: flutter + + # Firebase Core (Required for all Firebase services) + firebase_core: 3.12.1 + http: 1.3.0 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.8 + cloud_firestore: ^5.6.5 dev_dependencies: flutter_test: diff --git a/ai_friend/test/widget_test.dart b/ai_friend/test/widget_test.dart index b2cd065..cefc82d 100644 --- a/ai_friend/test/widget_test.dart +++ b/ai_friend/test/widget_test.dart @@ -13,7 +13,7 @@ import 'package:ai_friend/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); + await tester.pumpWidget(MyApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); diff --git a/ai_friend/windows/flutter/generated_plugin_registrant.cc b/ai_friend/windows/flutter/generated_plugin_registrant.cc index 8b6d468..eeeeb11 100644 --- a/ai_friend/windows/flutter/generated_plugin_registrant.cc +++ b/ai_friend/windows/flutter/generated_plugin_registrant.cc @@ -6,6 +6,12 @@ #include "generated_plugin_registrant.h" +#include +#include void RegisterPlugins(flutter::PluginRegistry* registry) { + CloudFirestorePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("CloudFirestorePluginCApi")); + FirebaseCorePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); } diff --git a/ai_friend/windows/flutter/generated_plugins.cmake b/ai_friend/windows/flutter/generated_plugins.cmake index b93c4c3..448a2c3 100644 --- a/ai_friend/windows/flutter/generated_plugins.cmake +++ b/ai_friend/windows/flutter/generated_plugins.cmake @@ -3,6 +3,8 @@ # list(APPEND FLUTTER_PLUGIN_LIST + cloud_firestore + firebase_core ) list(APPEND FLUTTER_FFI_PLUGIN_LIST