diff --git a/.gitignore b/.gitignore index 29a3a50..ae10787 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,7 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release + + +/lib/env/env.g.dart +.env \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 1a138b7..7130f67 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -26,9 +26,16 @@ + + + + UserUsecase(), ), ], - child: const MaterialApp(debugShowCheckedModeBanner: false, home: AuthGate()), + child: const MaterialApp( + debugShowCheckedModeBanner: false, home: AuthGate()), ); } } diff --git a/lib/pages/add_case_page.dart b/lib/pages/add_case_page.dart index b36ec1e..c6a3033 100644 --- a/lib/pages/add_case_page.dart +++ b/lib/pages/add_case_page.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'package:dart_openai/dart_openai.dart'; import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -155,24 +156,38 @@ class _AddCasePageState extends State { padding: EdgeInsets.symmetric(horizontal: 16), ), ), + // Submit button is here! ElevatedButton( onPressed: () async { - - // validation - if (_formKey.currentState!.validate()) { - _formKey.currentState!.save(); - } - // check for image - if (picBytes != null) { - // post image/case - await FirestoreModel().addCase(controllers, userUsecase, picFile!, picBytes!).then( - (CaseEntity caseEntity) { - // pass CaseEntity to ChatPage for OpenAI API call - Navigator.of(context).pushReplacement(MaterialPageRoute( - builder: (context) => ChatPage(caseEntity: caseEntity), - )); - }, - ); + // // validation + // if (_formKey.currentState!.validate()) { + // _formKey.currentState!.save(); + // } + // // check for image + // if (picBytes != null) { + // // post image/case + // await FirestoreModel().addCase(controllers, userUsecase, picFile!, picBytes!).then( + // (CaseEntity caseEntity) { + // // pass CaseEntity to ChatPage for OpenAI API call + // Navigator.of(context).pushReplacement(MaterialPageRoute( + // builder: (context) => ChatPage(caseEntity: caseEntity), + // )); + // }, + // ); + // } + // makeApiCall() function is at the bottom of the file + // please check if this implmementation is correct + if (_formKey.currentState != null && _formKey.currentState!.validate()) { + makeApiCall().then((response) { + Navigator.of(context).pop(); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text("Case added successfully"), + ), + ); + }).catchError((error) { + // Handle any errors here + }); } }, child: const Text("submit")) @@ -414,3 +429,54 @@ class _AddCasePageState extends State { } // end of pictures code } + +makeApiCall() async { + // the system message that will be sent to the request. + final systemMessage = OpenAIChatCompletionChoiceMessageModel( + content: [ + OpenAIChatCompletionChoiceMessageContentItemModel.text( + "return any message you are given as JSON.", + ), + ], + role: OpenAIChatMessageRole.assistant, + ); + + // the user message that will be sent to the request. + final userMessage = OpenAIChatCompletionChoiceMessageModel( + content: [ + OpenAIChatCompletionChoiceMessageContentItemModel.text( + "Hello, I am a chatbot created by OpenAI. How are you today?", // TODO: Engineer a custom prompt for the image case analysis + ), + + //! image url contents are allowed only for models with image support such gpt-4. + OpenAIChatCompletionChoiceMessageContentItemModel.imageUrl( + "https://placehold.co/600x400", // TODO: Send the image that was picked by the user + ), + ], + role: OpenAIChatMessageRole.user, + ); + +// all messages to be sent. + final requestMessages = [ + systemMessage, + userMessage, + ]; + +// the actual request. + OpenAIChatCompletionModel chatCompletion = await OpenAI.instance.chat.create( + model: "gpt-3.5-turbo-1106", // TODO: Change model to GPT-4 + responseFormat: {"type": "json_object"}, + seed: 6, + messages: requestMessages, + temperature: 0.2, + maxTokens: 500, + ); + + // print the response. + + // TODO: Handle the response from the API and put it into a case chat + print(chatCompletion.choices.first.message); // ... + print(chatCompletion.systemFingerprint); // ... + print(chatCompletion.usage.promptTokens); // ... + print(chatCompletion.id); // ... +} diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 2e145cc..3d029ff 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -45,11 +45,17 @@ class _HomePageState extends State { children: [ Text( "nuts & bolts.", - style: TextStyle(color: MyColours.secondaryColour, fontSize: 28, fontWeight: FontWeight.bold), + style: TextStyle( + color: MyColours.secondaryColour, + fontSize: 28, + fontWeight: FontWeight.bold), ), Text( "Welcome, ${user!.displayName}!", - style: TextStyle(color: Colors.white.withOpacity(0.8), fontSize: 18, fontWeight: FontWeight.w600), + style: TextStyle( + color: Colors.white.withOpacity(0.8), + fontSize: 18, + fontWeight: FontWeight.w600), ) ], ), @@ -85,11 +91,13 @@ class _HomePageState extends State { children: [ const Text( "Want something fixed?", - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15), + style: TextStyle( + fontWeight: FontWeight.bold, fontSize: 15), ), Text( "Get a technician now!", - style: TextStyle(fontSize: 14, color: Colors.grey[700]), + style: TextStyle( + fontSize: 14, color: Colors.grey[700]), ), ], ), @@ -106,7 +114,8 @@ class _HomePageState extends State { .limit(5) .snapshots(), builder: (context, snapshot) { - if (!snapshot.hasData || snapshot.connectionState == ConnectionState.waiting) { + if (!snapshot.hasData || + snapshot.connectionState == ConnectionState.waiting) { return Column( children: [ SizedBox( @@ -126,7 +135,8 @@ class _HomePageState extends State { children: [ const Text( "Your Cases", - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18), + style: TextStyle( + fontWeight: FontWeight.bold, fontSize: 18), ), const SizedBox( height: 10, @@ -137,7 +147,8 @@ class _HomePageState extends State { physics: const NeverScrollableScrollPhysics(), itemCount: snapshot.data!.size, itemBuilder: (context, index) { - CaseEntity caseEntity = CaseEntity.from(snapshot.data!.docs[index].data()); + CaseEntity caseEntity = CaseEntity.from( + snapshot.data!.docs[index].data()); return CaseCard(caseEntity: caseEntity); }, ), diff --git a/pubspec.lock b/pubspec.lock index b67ad7a..293d5c4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" + url: "https://pub.dev" + source: hosted + version: "67.0.0" _flutterfire_internals: dependency: transitive description: @@ -9,6 +17,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.38" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" + url: "https://pub.dev" + source: hosted + version: "6.4.1" animated_bottom_navigation_bar: dependency: "direct main" description: @@ -41,6 +57,70 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + build: + dependency: transitive + description: + name: build + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + build_config: + dependency: transitive + description: + name: build_config + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.dev" + source: hosted + version: "1.1.1" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" + url: "https://pub.dev" + source: hosted + version: "2.4.2" + build_runner: + dependency: "direct dev" + description: + name: build_runner + sha256: "644dc98a0f179b872f612d3eb627924b578897c629788e858157fa5e704ca0c7" + url: "https://pub.dev" + source: hosted + version: "2.4.11" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + sha256: e3c79f69a64bdfcd8a776a3c28db4eb6e3fb5356d013ae5eb2e52007706d5dbe + url: "https://pub.dev" + source: hosted + version: "7.3.1" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb + url: "https://pub.dev" + source: hosted + version: "8.9.2" cached_network_image: dependency: transitive description: @@ -73,6 +153,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.dev" + source: hosted + version: "2.0.3" clock: dependency: transitive description: @@ -105,6 +193,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 + url: "https://pub.dev" + source: hosted + version: "4.10.0" collection: dependency: transitive description: @@ -113,6 +209,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" cross_file: dependency: transitive description: @@ -137,6 +241,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + dart_openai: + dependency: "direct main" + description: + name: dart_openai + sha256: "853bb57fed6a71c3ba0324af5cb40c16d196cf3aa55b91d244964ae4a241ccf1" + url: "https://pub.dev" + source: hosted + version: "5.1.0" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" + url: "https://pub.dev" + source: hosted + version: "2.3.6" dash_chat_2: dependency: "direct main" description: @@ -169,6 +289,30 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.17" + envied: + dependency: "direct dev" + description: + name: envied + sha256: bbff9c76120e4dc5e2e36a46690cf0a26feb65e7765633f4e8d916bcd173a450 + url: "https://pub.dev" + source: hosted + version: "0.5.4+1" + envied_generator: + dependency: "direct dev" + description: + name: envied_generator + sha256: "517b70de08d13dcd40e97b4e5347e216a0b1c75c99e704f3c85c0474a392d14a" + url: "https://pub.dev" + source: hosted + version: "0.5.4+1" + equatable: + dependency: transitive + description: + name: equatable + sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 + url: "https://pub.dev" + source: hosted + version: "2.0.5" fake_async: dependency: transitive description: @@ -177,6 +321,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + fetch_api: + dependency: transitive + description: + name: fetch_api + sha256: "97f46c25b480aad74f7cc2ad7ccba2c5c6f08d008e68f95c1077286ce243d0e6" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + fetch_client: + dependency: transitive + description: + name: fetch_client + sha256: "9666ee14536778474072245ed5cba07db81ae8eb5de3b7bf4a2d1e2c49696092" + url: "https://pub.dev" + source: hosted + version: "1.1.2" ffi: dependency: transitive description: @@ -429,6 +589,22 @@ packages: description: flutter source: sdk version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 + url: "https://pub.dev" + source: hosted + version: "4.0.0" + glob: + dependency: transitive + description: + name: glob + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" + source: hosted + version: "2.1.2" google_identity_services_web: dependency: transitive description: @@ -477,6 +653,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.12.4+1" + graphs: + dependency: transitive + description: + name: graphs + sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + url: "https://pub.dev" + source: hosted + version: "2.3.1" html: dependency: transitive description: @@ -493,6 +677,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + url: "https://pub.dev" + source: hosted + version: "3.2.1" http_parser: dependency: transitive description: @@ -597,6 +789,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.19.0" + io: + dependency: transitive + description: + name: io + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + url: "https://pub.dev" + source: hosted + version: "1.0.4" js: dependency: transitive description: @@ -605,6 +805,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.7" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.dev" + source: hosted + version: "4.9.0" leak_tracker: dependency: transitive description: @@ -661,6 +869,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.0.3" + logging: + dependency: transitive + description: + name: logging + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + url: "https://pub.dev" + source: hosted + version: "1.2.0" markdown: dependency: transitive description: @@ -717,6 +933,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" path: dependency: "direct main" description: @@ -805,6 +1029,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" + source: hosted + version: "1.5.1" provider: dependency: "direct main" description: @@ -813,6 +1045,30 @@ packages: url: "https://pub.dev" source: hosted version: "6.1.2" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 + url: "https://pub.dev" + source: hosted + version: "1.3.0" + recase: + dependency: transitive + description: + name: recase + sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 + url: "https://pub.dev" + source: hosted + version: "4.1.0" rxdart: dependency: transitive description: @@ -821,11 +1077,35 @@ packages: url: "https://pub.dev" source: hosted version: "0.27.7" + shelf: + dependency: transitive + description: + name: shelf + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + url: "https://pub.dev" + source: hosted + version: "1.4.1" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" + url: "https://pub.dev" + source: hosted + version: "2.0.0" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" + url: "https://pub.dev" + source: hosted + version: "1.5.0" source_span: dependency: transitive description: @@ -874,6 +1154,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" + source: hosted + version: "2.1.0" string_scanner: dependency: transitive description: @@ -914,6 +1202,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.0" + timing: + dependency: transitive + description: + name: timing + sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + url: "https://pub.dev" + source: hosted + version: "1.0.1" typed_data: dependency: transitive description: @@ -1074,6 +1370,14 @@ packages: url: "https://pub.dev" source: hosted version: "14.2.1" + watcher: + dependency: transitive + description: + name: watcher + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + url: "https://pub.dev" + source: hosted + version: "1.1.0" web: dependency: transitive description: @@ -1082,6 +1386,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.1" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "24301d8c293ce6fe327ffe6f59d8fd8834735f0ec36e4fd383ec7ff8a64aa078" + url: "https://pub.dev" + source: hosted + version: "0.1.5" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: a2d56211ee4d35d9b344d9d4ce60f362e4f5d1aafb988302906bd732bc731276 + url: "https://pub.dev" + source: hosted + version: "3.0.0" win32: dependency: transitive description: @@ -1106,6 +1426,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.5.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" + source: hosted + version: "3.1.2" sdks: dart: ">=3.4.0 <4.0.0" flutter: ">=3.22.0" diff --git a/pubspec.yaml b/pubspec.yaml index fc34906..05293c0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -9,6 +9,7 @@ environment: dependencies: animated_bottom_navigation_bar: ^1.3.3 cloud_firestore: ^5.0.2 + dart_openai: ^5.1.0 dash_chat_2: ^0.0.21 dropdown_button2: ^2.3.9 firebase_auth: ^5.1.1 @@ -28,9 +29,12 @@ dependencies: swipe_cards: ^2.0.0+1 dev_dependencies: + build_runner: ^2.4.11 flutter_test: sdk: flutter flutter_lints: ^4.0.0 + envied: ^0.5.4+1 + envied_generator: ^0.5.4+1 flutter: uses-material-design: true