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