├── .flutter-plugins
├── .flutter-plugins-dependencies
├── .gitignore
├── .idea
├── .gitignore
├── Viki-2-OpenAI.iml
├── libraries
│ ├── Dart_Packages.xml
│ ├── Dart_SDK.xml
│ └── Flutter_Plugins.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── LICENSE
├── README.md
├── analysis_options.yaml
├── android
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ │ └── io
│ │ │ │ └── flutter
│ │ │ │ └── plugins
│ │ │ │ └── GeneratedPluginRegistrant.java
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── chatgpt
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v21
│ │ │ └── launch_background.xml
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── chatgpt_android.iml
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle
├── assets
├── Viki 2 AI.png
├── openai.svg
└── searching.json
├── chatgpt.iml
├── lib
├── errors
│ └── exceptions.dart
├── main.dart
├── models
│ ├── chat.dart
│ ├── images.dart
│ └── model.dart
├── network
│ ├── api_services.dart
│ ├── error_message.dart
│ └── network_client.dart
├── providers
│ ├── error_message.dart
│ ├── get_images_provider.dart
│ ├── get_message_provider.dart
│ └── get_models_provider.dart
├── src
│ └── pages
│ │ ├── chat_page.dart
│ │ ├── dalle_page.dart
│ │ ├── full_screen.dart
│ │ ├── home_page.dart
│ │ └── splash_page.dart
└── utils
│ ├── change_theme_button.dart
│ ├── constants.dart
│ ├── routes.dart
│ └── theme_provider.dart
├── pubspec.lock
├── pubspec.yaml
├── test
└── widget_test.dart
└── update_version.json
/.flutter-plugins:
--------------------------------------------------------------------------------
1 | # This is a generated file; do not edit or check into version control.
2 | image_downloader=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\image_downloader-0.31.0\\
3 | path_provider=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\path_provider-2.0.14\\
4 | path_provider_android=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\path_provider_android-2.0.24\\
5 | path_provider_foundation=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\path_provider_foundation-2.2.1\\
6 | path_provider_linux=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\path_provider_linux-2.1.10\\
7 | path_provider_windows=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\path_provider_windows-2.1.5\\
8 | shared_preferences=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\shared_preferences-2.1.0\\
9 | shared_preferences_android=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\shared_preferences_android-2.1.0\\
10 | shared_preferences_foundation=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\shared_preferences_foundation-2.2.0\\
11 | shared_preferences_linux=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\shared_preferences_linux-2.2.0\\
12 | shared_preferences_web=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\shared_preferences_web-2.1.0\\
13 | shared_preferences_windows=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\shared_preferences_windows-2.2.0\\
14 | sqflite=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\sqflite-2.2.6\\
15 | url_launcher=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\url_launcher-6.1.10\\
16 | url_launcher_android=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\url_launcher_android-6.0.26\\
17 | url_launcher_ios=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\url_launcher_ios-6.1.4\\
18 | url_launcher_linux=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\url_launcher_linux-3.0.4\\
19 | url_launcher_macos=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\url_launcher_macos-3.0.4\\
20 | url_launcher_web=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\url_launcher_web-2.0.16\\
21 | url_launcher_windows=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dev\\url_launcher_windows-3.0.5\\
22 |
--------------------------------------------------------------------------------
/.flutter-plugins-dependencies:
--------------------------------------------------------------------------------
1 | {"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"image_downloader","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\image_downloader-0.31.0\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.2.1\\\\","native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.2.0\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.2.6\\\\","native_build":true,"dependencies":[]},{"name":"url_launcher_ios","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\url_launcher_ios-6.1.4\\\\","native_build":true,"dependencies":[]}],"android":[{"name":"image_downloader","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\image_downloader-0.31.0\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_android-2.0.24\\\\","native_build":true,"dependencies":[]},{"name":"shared_preferences_android","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_android-2.1.0\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.2.6\\\\","native_build":true,"dependencies":[]},{"name":"url_launcher_android","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\url_launcher_android-6.0.26\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"path_provider_foundation","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.2.1\\\\","native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.2.0\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.2.6\\\\","native_build":true,"dependencies":[]},{"name":"url_launcher_macos","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\url_launcher_macos-3.0.4\\\\","native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.1.10\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_linux-2.2.0\\\\","native_build":false,"dependencies":["path_provider_linux"]},{"name":"url_launcher_linux","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\url_launcher_linux-3.0.4\\\\","native_build":true,"dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.1.5\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_windows-2.2.0\\\\","native_build":false,"dependencies":["path_provider_windows"]},{"name":"url_launcher_windows","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\url_launcher_windows-3.0.5\\\\","native_build":true,"dependencies":[]}],"web":[{"name":"shared_preferences_web","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_web-2.1.0\\\\","dependencies":[]},{"name":"url_launcher_web","path":"C:\\\\Users\\\\VIKRAMADITYA\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\url_launcher_web-2.0.16\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"image_downloader","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"sqflite","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_android","url_launcher_ios","url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_android","dependencies":[]},{"name":"url_launcher_ios","dependencies":[]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2023-04-08 10:12:21.827462","version":"3.7.7"}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://www.dartlang.org/guides/libraries/private-files
2 |
3 | # Files and directories created by pub
4 | .dart_tool/
5 | .packages
6 | build/
7 | # If you're building an application, you may want to check-in your pubspec.lock
8 | pubspec.lock
9 |
10 | # Directory created by dartdoc
11 | # If you don't generate documentation locally you can remove this line.
12 | doc/api/
13 |
14 | # Avoid committing generated Javascript files:
15 | *.dart.js
16 | *.info.json # Produced by the --dump-info flag.
17 | *.js # When generated by dart2js. Don't specify *.js if your
18 | # project includes source files written in JavaScript.
19 | *.js_
20 | *.js.deps
21 | *.js.map
22 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/Viki-2-OpenAI.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/Dart_Packages.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
--------------------------------------------------------------------------------
/.idea/libraries/Dart_SDK.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/.idea/libraries/Flutter_Plugins.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Vikramaditya
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Viki-2-OpenAI
2 |
3 | A Chatbot chat app built using the Flutter framework and OpenAI's ChatGPT-3 and Dall.E 2 language model.
4 |
5 |
6 |
7 | Get Release: [Download](https://github.com/VikramadityaDev/Viki-2-OpenAI/releases)
8 |
9 |
10 | ### Show some :heart: and star the repo.
11 |
12 |
13 | ## Features
14 |
15 | - Natural language understanding.
16 | - Human-like conversation.
17 | - Customizable to fit your use-case.
18 | - Lightweight, easy to integrate with other apps.
19 | - Open-source.
20 | - High quality images.
21 | - Text to image.
22 | - Light and Dark Mode Enabled.
23 | - Image Downloadable.
24 |
25 | ## Replacing API Key
26 |
27 | ```
28 | You need to use your own OpenAI API key.
29 | Just replace the OPEN_AI_API_KEY_HERE found in /lib/utils/constants.dart, with your own key.
30 | ```
31 |
32 | ## Prerequisites
33 |
34 | - Flutter SDK
35 | - API key for OpenAI GPT-3 [Available here](https://beta.openai.com/account/api-keys)
36 |
37 |
38 | ### Development by
39 |
40 | - OpenAI - https://openai.com
41 | - Flutter - https://flutter.dev/
42 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at
17 | # https://dart-lang.github.io/linter/lints/index.html.
18 | #
19 | # Instead of disabling a lint rule for the entire project in the
20 | # section below, it can also be suppressed for a single line of code
21 | # or a specific dart file by using the `// ignore: name_of_lint` and
22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
23 | # producing the lint.
24 | rules:
25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27 |
28 | # Additional information about this file can be found at
29 | # https://dart.dev/guides/language/analysis-options
30 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion 33
30 | ndkVersion flutter.ndkVersion
31 |
32 | compileOptions {
33 | sourceCompatibility JavaVersion.VERSION_1_8
34 | targetCompatibility JavaVersion.VERSION_1_8
35 | }
36 |
37 | kotlinOptions {
38 | jvmTarget = '1.8'
39 | }
40 |
41 | sourceSets {
42 | main.java.srcDirs += 'src/main/kotlin'
43 | }
44 |
45 | defaultConfig {
46 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
47 | applicationId "com.example.chatgpt"
48 | // You can update the following values to match your application needs.
49 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
50 | minSdkVersion 19
51 | targetSdkVersion flutter.targetSdkVersion
52 | versionCode flutterVersionCode.toInteger()
53 | versionName flutterVersionName
54 | multiDexEnabled true
55 | }
56 |
57 | buildTypes {
58 | release {
59 | // TODO: Add your own signing config for the release build.
60 | // Signing with the debug keys for now, so `flutter run --release` works.
61 | signingConfig signingConfigs.debug
62 | }
63 | }
64 | }
65 |
66 | flutter {
67 | source '../..'
68 | }
69 |
70 | dependencies {
71 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
72 | }
73 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
11 |
19 |
23 |
27 |
28 |
29 |
30 |
31 |
32 |
34 |
37 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java:
--------------------------------------------------------------------------------
1 | package io.flutter.plugins;
2 |
3 | import androidx.annotation.Keep;
4 | import androidx.annotation.NonNull;
5 | import io.flutter.Log;
6 |
7 | import io.flutter.embedding.engine.FlutterEngine;
8 |
9 | /**
10 | * Generated file. Do not edit.
11 | * This file is generated by the Flutter tool based on the
12 | * plugins that support the Android platform.
13 | */
14 | @Keep
15 | public final class GeneratedPluginRegistrant {
16 | private static final String TAG = "GeneratedPluginRegistrant";
17 | public static void registerWith(@NonNull FlutterEngine flutterEngine) {
18 | try {
19 | flutterEngine.getPlugins().add(new com.ko2ic.imagedownloader.ImageDownloaderPlugin());
20 | } catch(Exception e) {
21 | Log.e(TAG, "Error registering plugin image_downloader, com.ko2ic.imagedownloader.ImageDownloaderPlugin", e);
22 | }
23 | try {
24 | flutterEngine.getPlugins().add(new io.flutter.plugins.pathprovider.PathProviderPlugin());
25 | } catch(Exception e) {
26 | Log.e(TAG, "Error registering plugin path_provider_android, io.flutter.plugins.pathprovider.PathProviderPlugin", e);
27 | }
28 | try {
29 | flutterEngine.getPlugins().add(new io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin());
30 | } catch(Exception e) {
31 | Log.e(TAG, "Error registering plugin shared_preferences_android, io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin", e);
32 | }
33 | try {
34 | flutterEngine.getPlugins().add(new com.tekartik.sqflite.SqflitePlugin());
35 | } catch(Exception e) {
36 | Log.e(TAG, "Error registering plugin sqflite, com.tekartik.sqflite.SqflitePlugin", e);
37 | }
38 | try {
39 | flutterEngine.getPlugins().add(new io.flutter.plugins.urllauncher.UrlLauncherPlugin());
40 | } catch(Exception e) {
41 | Log.e(TAG, "Error registering plugin url_launcher_android, io.flutter.plugins.urllauncher.UrlLauncherPlugin", e);
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/example/chatgpt/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.chatgpt
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VikramadityaDev/Viki-2-OpenAI/b8f070be80ac7e489ae6eccf3011cf368a1a3285/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VikramadityaDev/Viki-2-OpenAI/b8f070be80ac7e489ae6eccf3011cf368a1a3285/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VikramadityaDev/Viki-2-OpenAI/b8f070be80ac7e489ae6eccf3011cf368a1a3285/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VikramadityaDev/Viki-2-OpenAI/b8f070be80ac7e489ae6eccf3011cf368a1a3285/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VikramadityaDev/Viki-2-OpenAI/b8f070be80ac7e489ae6eccf3011cf368a1a3285/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.6.10'
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:7.1.2'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | mavenCentral()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/android/chatgpt_android.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VikramadityaDev/Viki-2-OpenAI/b8f070be80ac7e489ae6eccf3011cf368a1a3285/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
6 |
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/android/local.properties:
--------------------------------------------------------------------------------
1 | sdk.dir=C:\\Users\\VIKRAMADITYA\\AppData\\Local\\Android\\sdk
2 | flutter.sdk=C:\\src\\flutter
3 | flutter.buildMode=release
4 | flutter.versionName=1.0.0
5 | flutter.versionCode=1
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/assets/Viki 2 AI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VikramadityaDev/Viki-2-OpenAI/b8f070be80ac7e489ae6eccf3011cf368a1a3285/assets/Viki 2 AI.png
--------------------------------------------------------------------------------
/assets/openai.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/chatgpt.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/lib/errors/exceptions.dart:
--------------------------------------------------------------------------------
1 | import 'package:dio/dio.dart';
2 |
3 | // Represent exceptions from Server/Remote data source.
4 | class RemoteException implements Exception {
5 | DioError dioError;
6 |
7 | RemoteException({required this.dioError});
8 | }
9 |
10 | // Represent exceptions from Cache.
11 | class LocalException implements Exception {
12 | String error;
13 |
14 | LocalException(this.error);
15 | }
16 |
17 | class RouteException implements Exception {
18 | final String message;
19 | RouteException(this.message);
20 | }
21 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:chatgpt/src/pages/splash_page.dart';
2 | import 'package:chatgpt/utils/theme_provider.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/services.dart';
5 | import 'package:provider/provider.dart';
6 |
7 | void main() async {
8 | WidgetsFlutterBinding.ensureInitialized();
9 | SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
10 | statusBarColor: Colors.transparent,
11 | ));
12 | runApp(const MyApp());
13 | }
14 |
15 | class MyApp extends StatelessWidget {
16 | const MyApp({super.key});
17 |
18 | @override
19 | Widget build(BuildContext context) => ChangeNotifierProvider(
20 | create: (context) => ThemeProvider(),
21 | builder: (context, _) {
22 | final themeProvider = Provider.of(context);
23 | return MaterialApp(
24 | title: 'Viki-2 A.I',
25 | debugShowCheckedModeBanner: false,
26 | themeMode: themeProvider.themeMode,
27 | theme: MyThemes.lightTheme,
28 | darkTheme: MyThemes.darkTheme,
29 | home: const SplashPage(),
30 | );
31 | },
32 | );
33 | }
34 |
35 |
36 | // Code Updated to latest version.
--------------------------------------------------------------------------------
/lib/models/chat.dart:
--------------------------------------------------------------------------------
1 | class Chat {
2 | final String msg;
3 | final int chat;
4 | Chat({
5 | required this.msg,
6 | required this.chat,
7 | });
8 |
9 | factory Chat.fromJson(Map json) => Chat(
10 | chat: json['chat'],
11 | msg: json['msg'],
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/lib/models/images.dart:
--------------------------------------------------------------------------------
1 | class Images {
2 | final String url;
3 |
4 | Images({
5 | required this.url,
6 | });
7 |
8 | factory Images.fromJson(Map json) => Images(
9 | url: json['url'],
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/lib/models/model.dart:
--------------------------------------------------------------------------------
1 | class Model {
2 | final String id;
3 | final int created;
4 | final String root;
5 |
6 | Model({
7 | required this.id,
8 | required this.root,
9 | required this.created,
10 | });
11 |
12 | factory Model.fromJson(Map json) => Model(
13 | id: json['id'],
14 | root: json['root'],
15 | created: json['created'],
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/lib/network/api_services.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:logger/logger.dart';
5 |
6 | import '../errors/exceptions.dart';
7 | import '../models/chat.dart';
8 | import '../models/images.dart';
9 | import '../models/model.dart';
10 |
11 | import '../utils/constants.dart';
12 | import 'error_message.dart';
13 | import 'network_client.dart';
14 |
15 | Future> submitGetImagesForm({
16 | required BuildContext context,
17 | required String prompt,
18 | required int n,
19 | }) async {
20 | //
21 | NetworkClient networkClient = NetworkClient();
22 | List imagesList = [];
23 | try {
24 | final res = await networkClient.post(
25 | '${BASE_URL}images/generations',
26 | {"prompt": prompt, "n": n, "size": "256x256"},
27 | token: OPEN_API_KEY,
28 | );
29 | Map mp = jsonDecode(res.toString());
30 | debugPrint(mp.toString());
31 | if (mp['data'].length > 0) {
32 | imagesList = List.generate(mp['data'].length, (i) {
33 | return Images.fromJson({
34 | 'url': mp['data'][i]['url'],
35 | });
36 | });
37 | debugPrint(imagesList.toString());
38 | }
39 | } on RemoteException catch (e) {
40 | Logger().e(e.dioError);
41 | errorMessage(context);
42 | }
43 | return imagesList;
44 | }
45 |
46 | Future> submitGetChatsForm({
47 | required BuildContext context,
48 | required String prompt,
49 | required int tokenValue,
50 | String? model,
51 | }) async {
52 | //
53 | NetworkClient networkClient = NetworkClient();
54 | List chatList = [];
55 | try {
56 | final res = await networkClient.post(
57 | "${BASE_URL}completions",
58 | {
59 | "model": model ?? "text-davinci-003",
60 | "prompt": prompt,
61 | "temperature": 0,
62 | "max_tokens": tokenValue
63 | },
64 | token: OPEN_API_KEY,
65 | );
66 | Map mp = jsonDecode(res.toString());
67 | debugPrint(mp.toString());
68 | if (mp['choices'].length > 0) {
69 | chatList = List.generate(mp['choices'].length, (i) {
70 | return Chat.fromJson({
71 | 'msg': mp['choices'][i]['text'],
72 | 'chat': 1,
73 | });
74 | });
75 | debugPrint(chatList.toString());
76 | }
77 | } on RemoteException catch (e) {
78 | Logger().e(e.dioError);
79 | errorMessage(context);
80 | }
81 | return chatList;
82 | }
83 |
84 | Future> submitGetModelsForm({
85 | required BuildContext context,
86 | }) async {
87 | //
88 | NetworkClient networkClient = NetworkClient();
89 | List modelsList = [];
90 | try {
91 | final res = await networkClient.get(
92 | "${BASE_URL}models",
93 | token: OPEN_API_KEY,
94 | );
95 | Map mp = jsonDecode(res.toString());
96 | debugPrint(mp.toString());
97 | if (mp['data'].length > 0) {
98 | modelsList = List.generate(mp['data'].length, (i) {
99 | return Model.fromJson({
100 | 'id': mp['data'][i]['id'],
101 | 'created': mp['data'][i]['created'],
102 | 'root': mp['data'][i]['root'],
103 | });
104 | });
105 | debugPrint(modelsList.toString());
106 | }
107 | } on RemoteException catch (e) {
108 | Logger().e(e.dioError);
109 | errorMessage(context);
110 | }
111 | return modelsList;
112 | }
113 |
--------------------------------------------------------------------------------
/lib/network/error_message.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | void errorMessage(BuildContext context) {
4 | ScaffoldMessenger.of(context).showSnackBar(
5 | const SnackBar(
6 | content: Text("Something went wrong. please try again later"),
7 | backgroundColor: Colors.lightBlue,
8 | ),
9 | );
10 | Navigator.pop(context);
11 | }
12 |
--------------------------------------------------------------------------------
/lib/network/network_client.dart:
--------------------------------------------------------------------------------
1 | import 'package:dio/dio.dart';
2 |
3 | import '../errors/exceptions.dart';
4 |
5 | class NetworkClient {
6 | Dio _dio = Dio();
7 | NetworkClient({String? baseUrl}) {
8 | baseUrl ??= "";
9 | BaseOptions baseOptions = BaseOptions(
10 | // receiveTimeout: 20000,
11 | // connectTimeout: 30000,
12 | baseUrl: baseUrl,
13 | maxRedirects: 2,
14 | );
15 | _dio = Dio(baseOptions);
16 | // adding logging interceptor.
17 | _dio.interceptors.add(LogInterceptor(
18 | requestBody: false,
19 | error: true,
20 | request: false,
21 | requestHeader: false,
22 | responseBody: true,
23 | responseHeader: false,
24 | ));
25 | }
26 |
27 | // for HTTP.GET Request.
28 | Future get(String url,
29 | {Map? params, String? token}) async {
30 | Response response;
31 | try {
32 | Map map = {"Accept": "application/json"};
33 | if (token != null) map.addAll({"Authorization": "Bearer $token"});
34 |
35 | response = await _dio.get(url,
36 | queryParameters: params,
37 | options: Options(
38 | headers: map,
39 | ));
40 | } on DioError catch (exception) {
41 | throw RemoteException(dioError: exception);
42 | }
43 | return response;
44 | }
45 |
46 | // for HTTP.POST Request.
47 | Future post(String url, Map params,
48 | {String? token}) async {
49 | Response response;
50 | try {
51 | Map map = {"Accept": "application/json"};
52 | if (token != null) {
53 | map.addAll({"Authorization": "Bearer $token"});
54 | }
55 | response = await _dio.post(url,
56 | data: params,
57 | options: Options(
58 | headers: map,
59 | responseType: ResponseType.json,
60 | validateStatus: (_) => true,
61 | ));
62 | } on DioError catch (exception) {
63 | throw RemoteException(dioError: exception);
64 | }
65 | return response;
66 | }
67 |
68 | // for HTTP.POST Request.
69 | Future put(String url, Map params,
70 | {String? token}) async {
71 | Response response;
72 | try {
73 | Map map = {"Accept": "application/json"};
74 | if (token != null) {
75 | map.addAll({"Authorization": "Bearer $token"});
76 | }
77 | response = await _dio.put(url,
78 | data: params,
79 | options: Options(
80 | headers: map,
81 | responseType: ResponseType.json,
82 | validateStatus: (_) => true,
83 | ));
84 | } on DioError catch (exception) {
85 | throw RemoteException(dioError: exception);
86 | }
87 | return response;
88 | }
89 |
90 | // for HTTP.PATCH Request.
91 | Future patch(String url, Map params) async {
92 | Response response;
93 | try {
94 | response = await _dio.patch(url,
95 | data: params,
96 | options: Options(
97 | responseType: ResponseType.json,
98 | ));
99 | } on DioError catch (exception) {
100 | throw RemoteException(dioError: exception);
101 | }
102 | return response;
103 | }
104 |
105 | // for download Request.
106 | Future download(String url, String pathName,
107 | void Function(int, int)? onReceiveProgress) async {
108 | Response response;
109 | try {
110 | response = await _dio.download(
111 | url,
112 | pathName,
113 | onReceiveProgress: onReceiveProgress,
114 | );
115 | } on DioError catch (exception) {
116 | throw RemoteException(dioError: exception);
117 | }
118 | return response;
119 | }
120 |
121 | // for fileUpload Request.
122 | Future fileUpload(String url, FormData params) async {
123 | Response response;
124 | try {
125 | response = await _dio.post(url,
126 | data: params,
127 | options: Options(
128 | responseType: ResponseType.json,
129 | ));
130 | } on DioError catch (exception) {
131 | throw RemoteException(dioError: exception);
132 | }
133 | return response;
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/lib/providers/error_message.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | void errorMessage(BuildContext context) {
4 | ScaffoldMessenger.of(context).showSnackBar(
5 | const SnackBar(
6 | content: Text("Something went wrong. please try again later"),
7 | backgroundColor: Colors.lightBlue,
8 | ),
9 | );
10 | Navigator.pop(context);
11 | }
12 |
--------------------------------------------------------------------------------
/lib/providers/get_images_provider.dart:
--------------------------------------------------------------------------------
1 | // import 'dart:convert';
2 |
3 | // import 'package:chatgpt/models/images.dart';
4 | // import 'package:flutter/material.dart';
5 | // import 'package:logger/logger.dart';
6 |
7 | // import '../errors/exceptions.dart';
8 | // import '../networks/network_client.dart';
9 | // import '../utils/constants.dart';
10 | // import 'error_message.dart';
11 |
12 | // Future> submitGetImagesForm({
13 | // required BuildContext context,
14 | // required String prompt,
15 | // required int n,
16 | // }) async {
17 | // //
18 | // NetworkClient networkClient = NetworkClient();
19 | // List imagesList = [];
20 | // try {
21 | // final res = await networkClient.post(
22 | // 'https://api.openai.com/v1/images/generations',
23 | // {"prompt": prompt, "n": n, "size": "1024x1024"},
24 | // token: OPEN_API_KEY,
25 | // );
26 | // Map mp = jsonDecode(res.toString());
27 | // debugPrint(mp.toString());
28 | // if (mp['data'].length > 0) {
29 | // imagesList = List.generate(mp['data'].length, (i) {
30 | // return Images.fromJson({
31 | // 'url': mp['data'][i]['url'],
32 | // });
33 | // });
34 | // debugPrint(imagesList.toString());
35 | // }
36 | // } on RemoteException catch (e) {
37 | // Logger().e(e.dioError);
38 | // errorMessage(context);
39 | // }
40 | // return imagesList;
41 | // }
42 |
--------------------------------------------------------------------------------
/lib/providers/get_message_provider.dart:
--------------------------------------------------------------------------------
1 | // import 'dart:convert';
2 |
3 | // import 'package:chatgpt/models/chat.dart';
4 | // import 'package:flutter/material.dart';
5 | // import 'package:logger/logger.dart';
6 |
7 | // import '../errors/exceptions.dart';
8 | // import '../networks/network_client.dart';
9 | // import '../utils/constants.dart';
10 | // import 'error_message.dart';
11 |
12 | // Future> submitGetChatsForm({
13 | // required BuildContext context,
14 | // required String prompt,
15 | // required int tokenValue,
16 | // String? model,
17 | // }) async {
18 | // //
19 | // NetworkClient networkClient = NetworkClient();
20 | // List chatList = [];
21 | // try {
22 | // final res = await networkClient.post(
23 | // "https://api.openai.com/v1/completions",
24 | // {
25 | // "model": model ?? "text-davinci-003",
26 | // "prompt": prompt,
27 | // "temperature": 0,
28 | // "max_tokens": tokenValue
29 | // },
30 | // token: OPEN_API_KEY,
31 | // );
32 | // Map mp = jsonDecode(res.toString());
33 | // debugPrint(mp.toString());
34 | // if (mp['choices'].length > 0) {
35 | // chatList = List.generate(mp['choices'].length, (i) {
36 | // return Chat.fromJson({
37 | // 'msg': mp['choices'][i]['text'],
38 | // 'chat': 1,
39 | // });
40 | // });
41 | // debugPrint(chatList.toString());
42 | // }
43 | // } on RemoteException catch (e) {
44 | // Logger().e(e.dioError);
45 | // errorMessage(context);
46 | // }
47 | // return chatList;
48 | // }
49 |
--------------------------------------------------------------------------------
/lib/providers/get_models_provider.dart:
--------------------------------------------------------------------------------
1 | // import 'dart:convert';
2 |
3 | // import 'package:chatgpt/models/model.dart';
4 | // import 'package:flutter/material.dart';
5 | // import 'package:logger/logger.dart';
6 |
7 | // import '../errors/exceptions.dart';
8 | // import '../networks/network_client.dart';
9 | // import '../utils/constants.dart';
10 | // import 'error_message.dart';
11 |
12 | // Future> submitGetModelsForm({
13 | // required BuildContext context,
14 | // }) async {
15 | // //
16 | // NetworkClient networkClient = NetworkClient();
17 | // List modelsList = [];
18 | // try {
19 | // final res = await networkClient.get(
20 | // "https://api.openai.com/v1/models",
21 | // token: OPEN_API_KEY,
22 | // );
23 | // Map mp = jsonDecode(res.toString());
24 | // debugPrint(mp.toString());
25 | // if (mp['data'].length > 0) {
26 | // modelsList = List.generate(mp['data'].length, (i) {
27 | // return Model.fromJson({
28 | // 'id': mp['data'][i]['id'],
29 | // 'created': mp['data'][i]['created'],
30 | // 'root': mp['data'][i]['root'],
31 | // });
32 | // });
33 | // debugPrint(modelsList.toString());
34 | // }
35 | // } on RemoteException catch (e) {
36 | // Logger().e(e.dioError);
37 | // errorMessage(context);
38 | // }
39 | // return modelsList;
40 | // }
41 |
--------------------------------------------------------------------------------
/lib/src/pages/chat_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:animated_text_kit/animated_text_kit.dart';
2 | import 'package:chatgpt/models/model.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/services.dart';
5 | import 'package:shared_preferences/shared_preferences.dart';
6 |
7 | import '../../models/chat.dart';
8 | import '../../network/api_services.dart';
9 |
10 | class ChatPage extends StatefulWidget {
11 | const ChatPage({super.key});
12 |
13 | @override
14 | State createState() => _ChatPageState();
15 | }
16 |
17 | class _ChatPageState extends State {
18 | String messagePrompt = '';
19 | int tokenValue = 500;
20 | List chatList = [];
21 | List modelsList = [];
22 | late SharedPreferences prefs;
23 | @override
24 | void initState() {
25 | super.initState();
26 | getModels();
27 | initPrefs();
28 | }
29 |
30 | void getModels() async {
31 | modelsList = await submitGetModelsForm(context: context);
32 | }
33 |
34 | List> get models {
35 | List> menuItems =
36 | List.generate(modelsList.length, (i) {
37 | return DropdownMenuItem(
38 | value: modelsList[i].id,
39 | child: Text(modelsList[i].id),
40 | );
41 | });
42 | return menuItems;
43 | }
44 |
45 | void initPrefs() async {
46 | prefs = await SharedPreferences.getInstance();
47 | tokenValue = prefs.getInt("token") ?? 500;
48 | }
49 |
50 | TextEditingController mesageController = TextEditingController();
51 | @override
52 | Widget build(BuildContext context) {
53 | return Scaffold(
54 | backgroundColor: Theme.of(context).scaffoldBackgroundColor,
55 | body: SafeArea(
56 | child: Stack(
57 | children: [
58 | Column(
59 | children: [
60 | _topChat(),
61 | _bodyChat(),
62 | const SizedBox(
63 | height: 75,
64 | )
65 | ],
66 | ),
67 | _formChat(),
68 | ],
69 | ),
70 | ),
71 | );
72 | }
73 |
74 | void saveData(int value) {
75 | prefs.setInt("token", value);
76 | }
77 |
78 | int getData() {
79 | return prefs.getInt("token") ?? 1;
80 | }
81 |
82 | _topChat() {
83 | return Container(
84 | padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
85 | child: Row(
86 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
87 | children: [
88 | Row(
89 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
90 | children: [
91 | GestureDetector(
92 | onTap: () => Navigator.of(context).pop(),
93 | child: const Icon(
94 | Icons.arrow_back_ios,
95 | size: 20,
96 | ),
97 | ),
98 | const Text(''),
99 | const Text(''),
100 | const Text(
101 | 'Chat GPT',
102 | style: TextStyle(
103 | fontSize: 20,
104 | fontWeight: FontWeight.bold,
105 | ),
106 | ),
107 | ],
108 | ),
109 | GestureDetector(
110 | onTap: () {
111 | showModalBottomSheet(
112 | context: context,
113 | backgroundColor: Colors.transparent,
114 | builder: (BuildContext context) {
115 | return StatefulBuilder(
116 | builder: (BuildContext context, StateSetter state) {
117 | return Container(
118 | height: 400,
119 | decoration: const BoxDecoration(
120 | // color: Colors.white,
121 | borderRadius: BorderRadius.only(
122 | topLeft: Radius.circular(20),
123 | topRight: Radius.circular(20),
124 | )),
125 | child: Column(
126 | mainAxisAlignment: MainAxisAlignment.start,
127 | mainAxisSize: MainAxisSize.min,
128 | children: [
129 | const Padding(
130 | padding: EdgeInsets.symmetric(vertical: 15.0),
131 | child: Text(
132 | 'Settings',
133 | style: TextStyle(
134 | // color: Colors.black,
135 | fontWeight: FontWeight.bold,
136 | ),
137 | ),
138 | ),
139 | Divider(
140 | color: Colors.grey.shade700,
141 | ),
142 | Padding(
143 | padding: const EdgeInsets.fromLTRB(20, 2, 20, 2),
144 | child: DropdownButtonFormField(
145 | items: models,
146 | borderRadius: const BorderRadius.only(),
147 | focusColor: Colors.amber,
148 | onChanged: (String? s) {},
149 | decoration: const InputDecoration(
150 | hintText: "Select Model"),
151 | ),
152 | ),
153 | const Padding(
154 | padding: EdgeInsets.fromLTRB(20, 20, 20, 2),
155 | child: Align(
156 | alignment: Alignment.topLeft,
157 | child: Text("Token")),
158 | ),
159 | Slider(
160 | min: 0,
161 | max: 1000,
162 | activeColor: Colors.black54,
163 | inactiveColor: Colors.grey.shade300,
164 | value: tokenValue.toDouble(),
165 | onChanged: (value) {
166 | state(() {
167 | tokenValue = value.round();
168 | });
169 | },
170 | ),
171 | Padding(
172 | padding: const EdgeInsets.symmetric(vertical: 10.0),
173 | child: Row(
174 | mainAxisAlignment: MainAxisAlignment.spaceAround,
175 | children: [
176 | InkWell(
177 | onTap: () {
178 | Navigator.of(context).pop(false);
179 | },
180 | child: Container(
181 | width:
182 | MediaQuery.of(context).size.width / 2.2,
183 | decoration: BoxDecoration(
184 | color: Colors.grey.shade200,
185 | borderRadius: BorderRadius.circular(40),
186 | ),
187 | padding: const EdgeInsets.symmetric(
188 | vertical: 15, horizontal: 20),
189 | child: const Center(
190 | child: Text(
191 | 'Cancel',
192 | style: TextStyle(
193 | color: Colors.black,
194 | fontWeight: FontWeight.bold,
195 | ),
196 | ),
197 | ),
198 | ),
199 | ),
200 | InkWell(
201 | onTap: () {
202 | saveData(tokenValue);
203 | Navigator.of(context).pop(false);
204 | },
205 | child: Container(
206 | width:
207 | MediaQuery.of(context).size.width / 2.2,
208 | decoration: BoxDecoration(
209 | color: const Color(0xFFE58500),
210 | borderRadius: BorderRadius.circular(40),
211 | ),
212 | padding: const EdgeInsets.symmetric(
213 | vertical: 15, horizontal: 20),
214 | child: const Center(
215 | child: Text(
216 | 'Save',
217 | style: TextStyle(
218 | color: Colors.black,
219 | fontWeight: FontWeight.bold,
220 | ),
221 | ),
222 | ),
223 | ),
224 | )
225 | ],
226 | ),
227 | ),
228 | ],
229 | ),
230 | );
231 | });
232 | },
233 | );
234 | },
235 | child: const Icon(
236 | Icons.more_vert_rounded,
237 | size: 25,
238 | // color: Colors.white,
239 | ),
240 | ),
241 | ],
242 | ),
243 | );
244 | }
245 |
246 | Widget chats() {
247 | return ListView.builder(
248 | shrinkWrap: true,
249 | physics: const NeverScrollableScrollPhysics(),
250 | scrollDirection: Axis.vertical,
251 | itemCount: chatList.length,
252 | itemBuilder: (context, index) => _itemChat(
253 | chat: chatList[index].chat,
254 | message: chatList[index].msg,
255 | ),
256 | );
257 | }
258 |
259 | Widget _bodyChat() {
260 | return Expanded(
261 | child: Container(
262 | padding: const EdgeInsets.only(left: 10, right: 10, top: 10),
263 | width: double.infinity,
264 | decoration: BoxDecoration(
265 | border: Border.all(color: Colors.grey),
266 | borderRadius: const BorderRadius.only(
267 | topLeft: Radius.circular(45), topRight: Radius.circular(45)),
268 | // color: Colors.white,
269 | ),
270 | child: ListView(
271 | shrinkWrap: true,
272 | scrollDirection: Axis.vertical,
273 | physics: const BouncingScrollPhysics(),
274 | children: [
275 | chats(),
276 | ],
277 | ),
278 | ),
279 | );
280 | }
281 |
282 | _itemChat({required int chat, required String message}) {
283 | return Row(
284 | mainAxisAlignment:
285 | chat == 0 ? MainAxisAlignment.end : MainAxisAlignment.start,
286 | crossAxisAlignment: CrossAxisAlignment.end,
287 | children: [
288 | Flexible(
289 | child: Container(
290 | margin: const EdgeInsets.only(
291 | left: 10,
292 | right: 10,
293 | top: 10,
294 | ),
295 | padding: const EdgeInsets.symmetric(
296 | vertical: 10,
297 | horizontal: 10,
298 | ),
299 | decoration: BoxDecoration(
300 | color: chat == 0 ? Colors.indigo.shade100 : Colors.indigo.shade50,
301 | borderRadius: chat == 0
302 | ? const BorderRadius.only(
303 | topLeft: Radius.circular(10),
304 | topRight: Radius.circular(10),
305 | bottomLeft: Radius.circular(10),
306 | )
307 | : const BorderRadius.only(
308 | topLeft: Radius.circular(10),
309 | topRight: Radius.circular(10),
310 | bottomRight: Radius.circular(10),
311 | ),
312 | ),
313 | child: chatWidget(message),
314 | ),
315 | ),
316 | ],
317 | );
318 | }
319 |
320 | Widget chatWidget(String text) {
321 | return SizedBox(
322 | width: 250.0,
323 | child: DefaultTextStyle(
324 | style: const TextStyle(
325 | color: Colors.black,
326 | fontSize: 16,
327 | ),
328 | child: AnimatedTextKit(
329 | animatedTexts: [
330 | TyperAnimatedText(
331 | text.replaceFirst('\n\n', ''),
332 | ),
333 | ],
334 | repeatForever: false,
335 | totalRepeatCount: 1,
336 | ),
337 | ),
338 | );
339 | }
340 |
341 | Widget _formChat() {
342 | return Positioned(
343 | child: Align(
344 | alignment: Alignment.bottomCenter,
345 | child: Container(
346 | padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
347 | // color: Colors.white,
348 | child: TextField(
349 | cursorColor: Colors.black87,
350 | style: const TextStyle(color: Colors.black),
351 | controller: mesageController,
352 | decoration: InputDecoration(
353 | hintText: 'Type your message...',
354 | hintStyle: const TextStyle(color: Colors.grey),
355 | suffixIcon: InkWell(
356 | onTap: (() async {
357 | messagePrompt = mesageController.text.toString();
358 | setState(() {
359 | chatList.add(Chat(msg: messagePrompt, chat: 0));
360 | mesageController.clear();
361 | });
362 | chatList.addAll(await submitGetChatsForm(
363 | context: context,
364 | prompt: messagePrompt,
365 | tokenValue: tokenValue,
366 | ));
367 | setState(() {});
368 | }),
369 | child: Container(
370 | decoration: BoxDecoration(
371 | borderRadius: BorderRadius.circular(10),
372 | color: Colors.black
373 | ),
374 | padding: const EdgeInsets.all(10),
375 | margin: const EdgeInsets.all(5),
376 | child: const Icon(
377 | Icons.send_rounded,
378 | color: Colors.white,
379 | size: 28,
380 | ),
381 | ),
382 | ),
383 | filled: true,
384 | fillColor: Colors.grey.shade100,
385 | labelStyle: const TextStyle(fontSize: 12),
386 | contentPadding: const EdgeInsets.all(20),
387 | enabledBorder: OutlineInputBorder(
388 | borderSide: BorderSide(color: Colors.grey.shade100,),
389 | borderRadius: BorderRadius.circular(10),
390 | ),
391 | focusedBorder: OutlineInputBorder(
392 | borderSide: BorderSide(color: Colors.grey.shade100,),
393 | borderRadius: BorderRadius.circular(10),
394 | ),
395 | ),
396 | ),
397 | ),
398 | ),
399 | );
400 | }
401 | }
402 |
--------------------------------------------------------------------------------
/lib/src/pages/dalle_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:cached_network_image/cached_network_image.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
4 | import 'package:shimmer/shimmer.dart';
5 |
6 | import '../../models/images.dart';
7 | import '../../network/api_services.dart';
8 | import 'full_screen.dart';
9 |
10 | class DallePage extends StatefulWidget {
11 | const DallePage({
12 | super.key,
13 | });
14 |
15 | @override
16 | State createState() => _DallePageState();
17 | }
18 |
19 | class _DallePageState extends State {
20 | TextEditingController searchController = TextEditingController();
21 | bool imagesAvailable = false;
22 | bool searching = false;
23 | final double _value = 10;
24 | List imagesList = [];
25 | @override
26 | void initState() {
27 | super.initState();
28 | imagesAvailable = imagesList.isNotEmpty ? true : false;
29 | }
30 |
31 | @override
32 | Widget build(BuildContext context) {
33 | return Scaffold(
34 | backgroundColor: Theme.of(context).scaffoldBackgroundColor,
35 | appBar: AppBar(
36 | backgroundColor: Colors.transparent,
37 | elevation: 0,
38 | leading: GestureDetector(
39 | onTap: () => Navigator.of(context).pop(),
40 | child: Icon(
41 | Icons.arrow_back_ios,
42 | size: 22,
43 | color: Theme.of(context).primaryColor,
44 | ),
45 | ),
46 | title: Text(
47 | 'DALL·E 2',
48 | style: TextStyle(
49 | fontSize: 20,
50 | fontWeight: FontWeight.bold,
51 | color: Theme.of(context).primaryColor,
52 | ),
53 | ),
54 | centerTitle: true,
55 | ),
56 | body: SafeArea(
57 | child: Container(
58 | margin: const EdgeInsets.symmetric(
59 | horizontal: 15,
60 | vertical: 5,
61 | ),
62 | child: Column(
63 | children: [
64 | _formChat(),
65 | Expanded(
66 | child: imagesAvailable
67 | ? MasonryGridView.count(
68 | crossAxisCount: 3,
69 | mainAxisSpacing: 10,
70 | itemCount: imagesList.length,
71 | crossAxisSpacing: 10,
72 | semanticChildCount: 6,
73 | itemBuilder: (context, index) {
74 | return InkWell(
75 | onTap: () {
76 | Navigator.of(context).push(
77 | CustomPageRoute(
78 | builder: (context) =>
79 | ImageView(imgPath: imagesList[index].url),
80 | ),
81 | );
82 | },
83 | child: Hero(
84 | tag: imagesList[index].url,
85 | child: Container(
86 | decoration: BoxDecoration(
87 | borderRadius: BorderRadius.circular(6)),
88 | height: index % 2 == 0 ? 180 : 250,
89 | width: MediaQuery.of(context).size.width / 3,
90 | child: ImageCard(
91 | imageData: imagesList[index].url,
92 | ),
93 | ),
94 | ),
95 | );
96 | },
97 | )
98 | : Center(
99 | child: searchingWidget(),
100 | ),
101 | ),
102 | ],
103 | ),
104 | ),
105 | ),
106 | );
107 | }
108 |
109 | Widget searchingWidget() {
110 | if (searching) {
111 | return const CircularProgressIndicator(
112 | color: Color(0x88000000),
113 | );
114 | } else {
115 | return const Text(
116 | "Search for any image",
117 | style: TextStyle(color: Colors.white),
118 | );
119 | }
120 | }
121 |
122 | Widget _formChat() {
123 | return Container(
124 | padding: const EdgeInsets.symmetric(
125 | vertical: 10,
126 | ),
127 | child: TextField(
128 | cursorColor: Colors.black87,
129 | controller: searchController,
130 | style: const TextStyle(color: Colors.black),
131 | decoration: InputDecoration(
132 | hintText: 'Type your message...',
133 | hintStyle: const TextStyle(color: Colors.grey),
134 | suffixIcon: InkWell(
135 | onTap: () async {
136 | setState(() {
137 | searching = true;
138 | });
139 | imagesList = await submitGetImagesForm(
140 | context: context,
141 | prompt: searchController.text.toString(),
142 | n: _value.round(),
143 | );
144 | setState(() {
145 | imagesAvailable = imagesList.isNotEmpty ? true : false;
146 | });
147 | },
148 | child: Container(
149 | decoration: BoxDecoration(
150 | borderRadius: BorderRadius.circular(10),
151 | color: Colors.black,
152 | ),
153 | padding: const EdgeInsets.all(10),
154 | margin: const EdgeInsets.all(5),
155 | child: const Icon(
156 | Icons.search,
157 | color: Colors.white,
158 | size: 28,
159 | ),
160 | ),
161 | ),
162 | filled: true,
163 | fillColor: Colors.grey.shade100,
164 | labelStyle: const TextStyle(fontSize: 12),
165 | contentPadding: const EdgeInsets.all(20),
166 | enabledBorder: OutlineInputBorder(
167 | borderSide: BorderSide(
168 | color: Colors.grey.shade100,
169 | ),
170 | borderRadius: BorderRadius.circular(10),
171 | ),
172 | focusedBorder: OutlineInputBorder(
173 | borderSide: BorderSide(
174 | color: Colors.grey.shade100,
175 | ),
176 | borderRadius: BorderRadius.circular(10),
177 | ),
178 | ),
179 | ),
180 | );
181 | }
182 | }
183 |
184 | class ImageCard extends StatelessWidget {
185 | const ImageCard({super.key, required this.imageData});
186 |
187 | final String imageData;
188 |
189 | @override
190 | Widget build(BuildContext context) {
191 | return ClipRRect(
192 | borderRadius: BorderRadius.circular(6.0),
193 | child: CachedNetworkImage(
194 | imageUrl: imageData,
195 | fit: BoxFit.cover,
196 | progressIndicatorBuilder: (context, url, downloadProgress) => SizedBox(
197 | height: 150,
198 | width: 150,
199 | child: Shimmer.fromColors(
200 | baseColor: Colors.grey.shade100,
201 | highlightColor: Colors.white,
202 | child: Container(
203 | height: 220,
204 | width: 130,
205 | decoration: BoxDecoration(
206 | color: Colors.white,
207 | borderRadius: BorderRadius.circular(4)),
208 | ),
209 | )),
210 | ),
211 | );
212 | }
213 | }
214 |
215 | class CustomPageRoute extends MaterialPageRoute {
216 | @override
217 | Duration get transitionDuration => const Duration(milliseconds: 500);
218 |
219 | CustomPageRoute({builder}) : super(builder: builder);
220 | }
221 |
--------------------------------------------------------------------------------
/lib/src/pages/full_screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:cached_network_image/cached_network_image.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:image_downloader/image_downloader.dart';
4 |
5 | class ImageView extends StatefulWidget {
6 | final String imgPath;
7 |
8 | const ImageView({super.key, required this.imgPath});
9 |
10 | @override
11 | State createState() => _ImageViewState();
12 | }
13 |
14 | class _ImageViewState extends State {
15 | @override
16 | Widget build(BuildContext context) {
17 | return Scaffold(
18 | body: Stack(
19 | children: [
20 | Hero(
21 | tag: widget.imgPath,
22 | child: SizedBox(
23 | height: MediaQuery.of(context).size.height,
24 | width: MediaQuery.of(context).size.width,
25 | child: CachedNetworkImage(
26 | imageUrl: widget.imgPath,
27 | placeholder: (context, url) => Container(
28 | color: const Color(0xfff5f8fd),
29 | ),
30 | fit: BoxFit.cover),
31 | ),
32 | ),
33 | Container(
34 | height: MediaQuery.of(context).size.height,
35 | width: MediaQuery.of(context).size.width,
36 | alignment: Alignment.bottomCenter,
37 | child: Column(
38 | mainAxisSize: MainAxisSize.min,
39 | children: [
40 | InkWell(
41 | onTap: () async {
42 | await ImageDownloader.downloadImage(widget.imgPath);
43 | },
44 | child: Stack(
45 | children: [
46 | Container(
47 | width: MediaQuery.of(context).size.width / 2,
48 | height: 50,
49 | decoration: BoxDecoration(
50 | color: const Color(0xff1C1B1B).withOpacity(0.8),
51 | borderRadius: BorderRadius.circular(40),
52 | ),
53 | ),
54 | Container(
55 | width: MediaQuery.of(context).size.width / 2,
56 | height: 50,
57 | alignment: Alignment.center,
58 | decoration: BoxDecoration(
59 | border:
60 | Border.all(color: Colors.white24, width: 1),
61 | borderRadius: BorderRadius.circular(40),
62 | gradient: const LinearGradient(
63 | colors: [
64 | Color(0x36FFFFFF),
65 | Color(0x0FFFFFFF)
66 | ],
67 | begin: FractionalOffset.topLeft,
68 | end: FractionalOffset.bottomRight)),
69 | child: const Text(
70 | "Download",
71 | style: TextStyle(
72 | color: Colors.white70,
73 | fontSize: 15,
74 | fontWeight: FontWeight.w500),
75 | ),
76 | ),
77 | ],
78 | )),
79 | const SizedBox(
80 | height: 50,
81 | )
82 | ],
83 | ),
84 | )
85 | ],
86 | ),
87 | );
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/lib/src/pages/home_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:chatgpt/src/pages/chat_page.dart';
2 | import 'package:chatgpt/src/pages/dalle_page.dart';
3 | import 'package:chatgpt/utils/change_theme_button.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:url_launcher/url_launcher.dart';
6 |
7 | class HomePage extends StatefulWidget {
8 | const HomePage({super.key});
9 |
10 | @override
11 | State createState() => _HomePageState();
12 | }
13 |
14 | class _HomePageState extends State {
15 | @override
16 | Widget build(BuildContext context) {
17 | return Scaffold(
18 | appBar: AppBar(
19 | title: Text(
20 | 'Viki-2 A.I',
21 | style: TextStyle(
22 | color: Theme.of(context).primaryColor,
23 | ),
24 | ),
25 | backgroundColor: Theme.of(context).scaffoldBackgroundColor,
26 | elevation: 0,
27 | centerTitle: true,
28 | actions: [
29 | ChangeThemeButtonWidget(),
30 | ],
31 | ),
32 | body: Padding(
33 | padding: const EdgeInsets.only(bottom: 50),
34 | child: Column(
35 | mainAxisAlignment: MainAxisAlignment.center,
36 | children: [
37 | SizedBox(
38 | height: 110,
39 | width: 115,
40 | child: Image.asset('assets/Viki 2 AI.png', fit: BoxFit.cover,),
41 | ),
42 | const SizedBox(
43 | height: 20,
44 | ),
45 | buttonWidget('DALL·E 2 By OpenAI', () {
46 | // _showInterstitialAd();
47 | Navigator.push(
48 | context,
49 | MaterialPageRoute(
50 | builder: (context) => const DallePage(),
51 | ),
52 | );
53 | }),
54 | buttonWidget(
55 | 'ChatGPT By OpenAI',
56 | () {
57 | // _showInterstitialAd();
58 | Navigator.push(
59 | context,
60 | MaterialPageRoute(
61 | builder: (context) => const ChatPage(),
62 | ),
63 | );
64 | },
65 | ),
66 | buttonWidget("Join Telegram", () {
67 | _launchUrl(
68 | Uri.parse(
69 | 'http://telegram.me/VikiMediaOfficial/',
70 | ),
71 | );
72 | }
73 | ),
74 | ],
75 | ),
76 | ),
77 | bottomNavigationBar: Container(
78 | alignment: Alignment.center,
79 | width: double.infinity,
80 | height: 50,
81 | child: const Text('Powered By VikiMedia Official'),
82 | ),
83 | );
84 | }
85 |
86 | Widget buttonWidget(String text, VoidCallback onTap) {
87 | return InkWell(
88 | onTap: onTap,
89 | child: Container(
90 | decoration: BoxDecoration(
91 | borderRadius: BorderRadius.circular(8),
92 | border: Border.all(
93 | color: Colors.grey.shade400,
94 | ),
95 | ),
96 | padding: const EdgeInsets.symmetric(
97 | vertical: 40,
98 | ),
99 | margin: const EdgeInsets.symmetric(
100 | horizontal: 10,
101 | vertical: 5,
102 | ),
103 | child: Center(
104 | child: Text(
105 | text,
106 | ),
107 | ),
108 | ),
109 | );
110 | }
111 |
112 | Future _launchUrl(Uri url) async {
113 | if (!await launchUrl(
114 | url,
115 | mode: LaunchMode.externalApplication,
116 | )) throw 'Could not launch $url';
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/lib/src/pages/splash_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:chatgpt/src/pages/home_page.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_svg/svg.dart';
4 |
5 | class SplashPage extends StatefulWidget {
6 | const SplashPage({Key? key}) : super(key: key);
7 |
8 | @override
9 | State createState() => _SplashPageState();
10 | }
11 |
12 | class _SplashPageState extends State {
13 | @override
14 | void initState() {
15 | super.initState();
16 | Future.delayed(const Duration(milliseconds: 1600), () {
17 | setState(() {
18 | // Here we are going to the City List Screen
19 | // we can make isProduction : true for showing active=true cities
20 | // we can make isProduction : false for showing active=false cities
21 | Navigator.pushReplacement(
22 | context,
23 | MaterialPageRoute(
24 | builder: (context) => const HomePage(),
25 | ),
26 | );
27 | });
28 | });
29 | }
30 |
31 | @override
32 | Widget build(BuildContext context) {
33 | return Scaffold(
34 | body: Center(
35 | child: SvgPicture.asset(
36 | 'assets/openai.svg',
37 | height: 130,
38 | ),
39 | ),
40 | );
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/lib/utils/change_theme_button.dart:
--------------------------------------------------------------------------------
1 | import 'package:chatgpt/utils/theme_provider.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:provider/provider.dart';
4 |
5 |
6 | class ChangeThemeButtonWidget extends StatelessWidget {
7 | @override
8 | Widget build(BuildContext context) {
9 | final themeProvider = Provider.of(context);
10 |
11 | return Switch.adaptive(
12 | value: themeProvider.isDarkMode,
13 | onChanged: (value){
14 | final provider = Provider.of(context, listen: false);
15 | provider.toggleTheme(value);
16 | }
17 | );
18 | }
19 | }
--------------------------------------------------------------------------------
/lib/utils/constants.dart:
--------------------------------------------------------------------------------
1 | // ignore_for_file: non_constant_identifier_names
2 |
3 | String OPEN_API_KEY = 'OPEN_AI_API_KEY_HERE';
4 |
5 | String BASE_URL = 'https://api.openai.com/v1/';
6 |
--------------------------------------------------------------------------------
/lib/utils/routes.dart:
--------------------------------------------------------------------------------
1 | import 'package:chatgpt/src/pages/chat_page.dart';
2 | import 'package:chatgpt/src/pages/dalle_page.dart';
3 | import 'package:flutter/material.dart';
4 |
5 | import '../errors/exceptions.dart';
6 |
7 | class RouteGenerator {
8 | static const String dalle = 'dalle';
9 | static const String chat = 'chat';
10 | RouteGenerator._();
11 |
12 | static Route generateRoute(RouteSettings settings) {
13 | switch (settings.name) {
14 | case dalle:
15 | return MaterialPageRoute(builder: (_) => const DallePage());
16 | case chat:
17 | return MaterialPageRoute(builder: (_) => const ChatPage());
18 |
19 | default:
20 | throw RouteException('Route not found');
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/utils/theme_provider.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class ThemeProvider extends ChangeNotifier {
4 | ThemeMode themeMode = ThemeMode.dark;
5 | bool get isDarkMode => themeMode == ThemeMode.dark;
6 |
7 | void toggleTheme(bool isOn){
8 | themeMode = isOn ? ThemeMode.dark : ThemeMode.light;
9 | notifyListeners();
10 | }
11 | }
12 |
13 | class MyThemes {
14 | static final darkTheme = ThemeData(
15 | scaffoldBackgroundColor: Colors.grey.shade900,
16 | primaryColor: Colors.white,
17 | colorScheme: const ColorScheme.dark(),
18 | );
19 |
20 | static final lightTheme = ThemeData(
21 | scaffoldBackgroundColor: Colors.white,
22 | primaryColor: Colors.black87,
23 | colorScheme: const ColorScheme.light(),
24 | );
25 | }
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | animated_text_kit:
5 | dependency: "direct main"
6 | description:
7 | name: animated_text_kit
8 | sha256: "37392a5376c9a1a503b02463c38bc0342ef814ddbb8f9977bc90f2a84b22fa92"
9 | url: "https://pub.dev"
10 | source: hosted
11 | version: "4.2.2"
12 | archive:
13 | dependency: transitive
14 | description:
15 | name: archive
16 | sha256: d6347d54a2d8028e0437e3c099f66fdb8ae02c4720c1e7534c9f24c10351f85d
17 | url: "https://pub.dev"
18 | source: hosted
19 | version: "3.3.6"
20 | args:
21 | dependency: transitive
22 | description:
23 | name: args
24 | sha256: "4cab82a83ffef80b262ddedf47a0a8e56ee6fbf7fe21e6e768b02792034dd440"
25 | url: "https://pub.dev"
26 | source: hosted
27 | version: "2.4.0"
28 | async:
29 | dependency: transitive
30 | description:
31 | name: async
32 | sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
33 | url: "https://pub.dev"
34 | source: hosted
35 | version: "2.10.0"
36 | boolean_selector:
37 | dependency: transitive
38 | description:
39 | name: boolean_selector
40 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
41 | url: "https://pub.dev"
42 | source: hosted
43 | version: "2.1.1"
44 | cached_network_image:
45 | dependency: "direct main"
46 | description:
47 | name: cached_network_image
48 | sha256: fd3d0dc1d451f9a252b32d95d3f0c3c487bc41a75eba2e6097cb0b9c71491b15
49 | url: "https://pub.dev"
50 | source: hosted
51 | version: "3.2.3"
52 | cached_network_image_platform_interface:
53 | dependency: transitive
54 | description:
55 | name: cached_network_image_platform_interface
56 | sha256: bb2b8403b4ccdc60ef5f25c70dead1f3d32d24b9d6117cfc087f496b178594a7
57 | url: "https://pub.dev"
58 | source: hosted
59 | version: "2.0.0"
60 | cached_network_image_web:
61 | dependency: transitive
62 | description:
63 | name: cached_network_image_web
64 | sha256: b8eb814ebfcb4dea049680f8c1ffb2df399e4d03bf7a352c775e26fa06e02fa0
65 | url: "https://pub.dev"
66 | source: hosted
67 | version: "1.0.2"
68 | characters:
69 | dependency: transitive
70 | description:
71 | name: characters
72 | sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
73 | url: "https://pub.dev"
74 | source: hosted
75 | version: "1.2.1"
76 | clock:
77 | dependency: transitive
78 | description:
79 | name: clock
80 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
81 | url: "https://pub.dev"
82 | source: hosted
83 | version: "1.1.1"
84 | collection:
85 | dependency: transitive
86 | description:
87 | name: collection
88 | sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
89 | url: "https://pub.dev"
90 | source: hosted
91 | version: "1.17.0"
92 | convert:
93 | dependency: transitive
94 | description:
95 | name: convert
96 | sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
97 | url: "https://pub.dev"
98 | source: hosted
99 | version: "3.1.1"
100 | crypto:
101 | dependency: transitive
102 | description:
103 | name: crypto
104 | sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67
105 | url: "https://pub.dev"
106 | source: hosted
107 | version: "3.0.2"
108 | cupertino_icons:
109 | dependency: "direct main"
110 | description:
111 | name: cupertino_icons
112 | sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
113 | url: "https://pub.dev"
114 | source: hosted
115 | version: "1.0.5"
116 | dio:
117 | dependency: "direct main"
118 | description:
119 | name: dio
120 | sha256: "0894a098594263fe1caaba3520e3016d8a855caeb010a882273189cca10f11e9"
121 | url: "https://pub.dev"
122 | source: hosted
123 | version: "5.1.1"
124 | fake_async:
125 | dependency: transitive
126 | description:
127 | name: fake_async
128 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
129 | url: "https://pub.dev"
130 | source: hosted
131 | version: "1.3.1"
132 | ffi:
133 | dependency: transitive
134 | description:
135 | name: ffi
136 | sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978
137 | url: "https://pub.dev"
138 | source: hosted
139 | version: "2.0.1"
140 | file:
141 | dependency: transitive
142 | description:
143 | name: file
144 | sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
145 | url: "https://pub.dev"
146 | source: hosted
147 | version: "6.1.4"
148 | flutter:
149 | dependency: "direct main"
150 | description: flutter
151 | source: sdk
152 | version: "0.0.0"
153 | flutter_blurhash:
154 | dependency: transitive
155 | description:
156 | name: flutter_blurhash
157 | sha256: "05001537bd3fac7644fa6558b09ec8c0a3f2eba78c0765f88912882b1331a5c6"
158 | url: "https://pub.dev"
159 | source: hosted
160 | version: "0.7.0"
161 | flutter_cache_manager:
162 | dependency: transitive
163 | description:
164 | name: flutter_cache_manager
165 | sha256: "32cd900555219333326a2d0653aaaf8671264c29befa65bbd9856d204a4c9fb3"
166 | url: "https://pub.dev"
167 | source: hosted
168 | version: "3.3.0"
169 | flutter_lints:
170 | dependency: "direct dev"
171 | description:
172 | name: flutter_lints
173 | sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
174 | url: "https://pub.dev"
175 | source: hosted
176 | version: "2.0.1"
177 | flutter_staggered_grid_view:
178 | dependency: "direct main"
179 | description:
180 | name: flutter_staggered_grid_view
181 | sha256: "1312314293acceb65b92754298754801b0e1f26a1845833b740b30415bbbcf07"
182 | url: "https://pub.dev"
183 | source: hosted
184 | version: "0.6.2"
185 | flutter_svg:
186 | dependency: "direct main"
187 | description:
188 | name: flutter_svg
189 | sha256: "12006889e2987c549c4c1ec1a5ba4ec4b24d34d2469ee5f9476c926dcecff266"
190 | url: "https://pub.dev"
191 | source: hosted
192 | version: "2.0.4"
193 | flutter_test:
194 | dependency: "direct dev"
195 | description: flutter
196 | source: sdk
197 | version: "0.0.0"
198 | flutter_web_plugins:
199 | dependency: transitive
200 | description: flutter
201 | source: sdk
202 | version: "0.0.0"
203 | http:
204 | dependency: transitive
205 | description:
206 | name: http
207 | sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482"
208 | url: "https://pub.dev"
209 | source: hosted
210 | version: "0.13.5"
211 | http_parser:
212 | dependency: transitive
213 | description:
214 | name: http_parser
215 | sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
216 | url: "https://pub.dev"
217 | source: hosted
218 | version: "4.0.2"
219 | image_downloader:
220 | dependency: "direct main"
221 | description:
222 | name: image_downloader
223 | sha256: "2b1c1d1fcfb6677175d009af3fc86914aee07684c12ea061f380ef1f44cae8df"
224 | url: "https://pub.dev"
225 | source: hosted
226 | version: "0.31.0"
227 | js:
228 | dependency: transitive
229 | description:
230 | name: js
231 | sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
232 | url: "https://pub.dev"
233 | source: hosted
234 | version: "0.6.5"
235 | lints:
236 | dependency: transitive
237 | description:
238 | name: lints
239 | sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593"
240 | url: "https://pub.dev"
241 | source: hosted
242 | version: "2.0.1"
243 | logger:
244 | dependency: "direct main"
245 | description:
246 | name: logger
247 | sha256: db2ff852ed77090ba9f62d3611e4208a3d11dfa35991a81ae724c113fcb3e3f7
248 | url: "https://pub.dev"
249 | source: hosted
250 | version: "1.3.0"
251 | lottie:
252 | dependency: "direct main"
253 | description:
254 | name: lottie
255 | sha256: "23522951540d20a57a60202ed7022e6376bed206a4eee1c347a91f58bd57eb9f"
256 | url: "https://pub.dev"
257 | source: hosted
258 | version: "2.3.2"
259 | matcher:
260 | dependency: transitive
261 | description:
262 | name: matcher
263 | sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
264 | url: "https://pub.dev"
265 | source: hosted
266 | version: "0.12.13"
267 | material_color_utilities:
268 | dependency: transitive
269 | description:
270 | name: material_color_utilities
271 | sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
272 | url: "https://pub.dev"
273 | source: hosted
274 | version: "0.2.0"
275 | meta:
276 | dependency: transitive
277 | description:
278 | name: meta
279 | sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
280 | url: "https://pub.dev"
281 | source: hosted
282 | version: "1.8.0"
283 | nested:
284 | dependency: transitive
285 | description:
286 | name: nested
287 | sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
288 | url: "https://pub.dev"
289 | source: hosted
290 | version: "1.0.0"
291 | octo_image:
292 | dependency: transitive
293 | description:
294 | name: octo_image
295 | sha256: "107f3ed1330006a3bea63615e81cf637433f5135a52466c7caa0e7152bca9143"
296 | url: "https://pub.dev"
297 | source: hosted
298 | version: "1.0.2"
299 | path:
300 | dependency: transitive
301 | description:
302 | name: path
303 | sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
304 | url: "https://pub.dev"
305 | source: hosted
306 | version: "1.8.2"
307 | path_parsing:
308 | dependency: transitive
309 | description:
310 | name: path_parsing
311 | sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf
312 | url: "https://pub.dev"
313 | source: hosted
314 | version: "1.0.1"
315 | path_provider:
316 | dependency: transitive
317 | description:
318 | name: path_provider
319 | sha256: c7edf82217d4b2952b2129a61d3ad60f1075b9299e629e149a8d2e39c2e6aad4
320 | url: "https://pub.dev"
321 | source: hosted
322 | version: "2.0.14"
323 | path_provider_android:
324 | dependency: transitive
325 | description:
326 | name: path_provider_android
327 | sha256: "019f18c9c10ae370b08dce1f3e3b73bc9f58e7f087bb5e921f06529438ac0ae7"
328 | url: "https://pub.dev"
329 | source: hosted
330 | version: "2.0.24"
331 | path_provider_foundation:
332 | dependency: transitive
333 | description:
334 | name: path_provider_foundation
335 | sha256: "818b2dc38b0f178e0ea3f7cf3b28146faab11375985d815942a68eee11c2d0f7"
336 | url: "https://pub.dev"
337 | source: hosted
338 | version: "2.2.1"
339 | path_provider_linux:
340 | dependency: transitive
341 | description:
342 | name: path_provider_linux
343 | sha256: "2ae08f2216225427e64ad224a24354221c2c7907e448e6e0e8b57b1eb9f10ad1"
344 | url: "https://pub.dev"
345 | source: hosted
346 | version: "2.1.10"
347 | path_provider_platform_interface:
348 | dependency: transitive
349 | description:
350 | name: path_provider_platform_interface
351 | sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec"
352 | url: "https://pub.dev"
353 | source: hosted
354 | version: "2.0.6"
355 | path_provider_windows:
356 | dependency: transitive
357 | description:
358 | name: path_provider_windows
359 | sha256: f53720498d5a543f9607db4b0e997c4b5438884de25b0f73098cc2671a51b130
360 | url: "https://pub.dev"
361 | source: hosted
362 | version: "2.1.5"
363 | pedantic:
364 | dependency: transitive
365 | description:
366 | name: pedantic
367 | sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602"
368 | url: "https://pub.dev"
369 | source: hosted
370 | version: "1.11.1"
371 | petitparser:
372 | dependency: transitive
373 | description:
374 | name: petitparser
375 | sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4"
376 | url: "https://pub.dev"
377 | source: hosted
378 | version: "5.1.0"
379 | platform:
380 | dependency: transitive
381 | description:
382 | name: platform
383 | sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
384 | url: "https://pub.dev"
385 | source: hosted
386 | version: "3.1.0"
387 | plugin_platform_interface:
388 | dependency: transitive
389 | description:
390 | name: plugin_platform_interface
391 | sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc"
392 | url: "https://pub.dev"
393 | source: hosted
394 | version: "2.1.4"
395 | pointycastle:
396 | dependency: transitive
397 | description:
398 | name: pointycastle
399 | sha256: c3120a968135aead39699267f4c74bc9a08e4e909e86bc1b0af5bfd78691123c
400 | url: "https://pub.dev"
401 | source: hosted
402 | version: "3.7.2"
403 | process:
404 | dependency: transitive
405 | description:
406 | name: process
407 | sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
408 | url: "https://pub.dev"
409 | source: hosted
410 | version: "4.2.4"
411 | provider:
412 | dependency: "direct main"
413 | description:
414 | name: provider
415 | sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f
416 | url: "https://pub.dev"
417 | source: hosted
418 | version: "6.0.5"
419 | rxdart:
420 | dependency: transitive
421 | description:
422 | name: rxdart
423 | sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb"
424 | url: "https://pub.dev"
425 | source: hosted
426 | version: "0.27.7"
427 | shared_preferences:
428 | dependency: "direct main"
429 | description:
430 | name: shared_preferences
431 | sha256: "858aaa72d8f61637d64e776aca82e1c67e6d9ee07979123c5d17115031c1b13b"
432 | url: "https://pub.dev"
433 | source: hosted
434 | version: "2.1.0"
435 | shared_preferences_android:
436 | dependency: transitive
437 | description:
438 | name: shared_preferences_android
439 | sha256: "8304d8a1f7d21a429f91dee552792249362b68a331ac5c3c1caf370f658873f6"
440 | url: "https://pub.dev"
441 | source: hosted
442 | version: "2.1.0"
443 | shared_preferences_foundation:
444 | dependency: transitive
445 | description:
446 | name: shared_preferences_foundation
447 | sha256: cf2a42fb20148502022861f71698db12d937c7459345a1bdaa88fc91a91b3603
448 | url: "https://pub.dev"
449 | source: hosted
450 | version: "2.2.0"
451 | shared_preferences_linux:
452 | dependency: transitive
453 | description:
454 | name: shared_preferences_linux
455 | sha256: "9d387433ca65717bbf1be88f4d5bb18f10508917a8fa2fb02e0fd0d7479a9afa"
456 | url: "https://pub.dev"
457 | source: hosted
458 | version: "2.2.0"
459 | shared_preferences_platform_interface:
460 | dependency: transitive
461 | description:
462 | name: shared_preferences_platform_interface
463 | sha256: fb5cf25c0235df2d0640ac1b1174f6466bd311f621574997ac59018a6664548d
464 | url: "https://pub.dev"
465 | source: hosted
466 | version: "2.2.0"
467 | shared_preferences_web:
468 | dependency: transitive
469 | description:
470 | name: shared_preferences_web
471 | sha256: "74083203a8eae241e0de4a0d597dbedab3b8fef5563f33cf3c12d7e93c655ca5"
472 | url: "https://pub.dev"
473 | source: hosted
474 | version: "2.1.0"
475 | shared_preferences_windows:
476 | dependency: transitive
477 | description:
478 | name: shared_preferences_windows
479 | sha256: "5e588e2efef56916a3b229c3bfe81e6a525665a454519ca51dbcc4236a274173"
480 | url: "https://pub.dev"
481 | source: hosted
482 | version: "2.2.0"
483 | shimmer:
484 | dependency: "direct main"
485 | description:
486 | name: shimmer
487 | sha256: "1f1009b5845a1f88f1c5630212279540486f97409e9fc3f63883e71070d107bf"
488 | url: "https://pub.dev"
489 | source: hosted
490 | version: "2.0.0"
491 | sky_engine:
492 | dependency: transitive
493 | description: flutter
494 | source: sdk
495 | version: "0.0.99"
496 | source_span:
497 | dependency: transitive
498 | description:
499 | name: source_span
500 | sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
501 | url: "https://pub.dev"
502 | source: hosted
503 | version: "1.9.1"
504 | sqflite:
505 | dependency: transitive
506 | description:
507 | name: sqflite
508 | sha256: "500d6fec583d2c021f2d25a056d96654f910662c64f836cd2063167b8f1fa758"
509 | url: "https://pub.dev"
510 | source: hosted
511 | version: "2.2.6"
512 | sqflite_common:
513 | dependency: transitive
514 | description:
515 | name: sqflite_common
516 | sha256: "963dad8c4aa2f814ce7d2d5b1da2f36f31bd1a439d8f27e3dc189bb9d26bc684"
517 | url: "https://pub.dev"
518 | source: hosted
519 | version: "2.4.3"
520 | stack_trace:
521 | dependency: transitive
522 | description:
523 | name: stack_trace
524 | sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
525 | url: "https://pub.dev"
526 | source: hosted
527 | version: "1.11.0"
528 | stream_channel:
529 | dependency: transitive
530 | description:
531 | name: stream_channel
532 | sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
533 | url: "https://pub.dev"
534 | source: hosted
535 | version: "2.1.1"
536 | string_scanner:
537 | dependency: transitive
538 | description:
539 | name: string_scanner
540 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
541 | url: "https://pub.dev"
542 | source: hosted
543 | version: "1.2.0"
544 | synchronized:
545 | dependency: transitive
546 | description:
547 | name: synchronized
548 | sha256: "33b31b6beb98100bf9add464a36a8dd03eb10c7a8cf15aeec535e9b054aaf04b"
549 | url: "https://pub.dev"
550 | source: hosted
551 | version: "3.0.1"
552 | term_glyph:
553 | dependency: transitive
554 | description:
555 | name: term_glyph
556 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
557 | url: "https://pub.dev"
558 | source: hosted
559 | version: "1.2.1"
560 | test_api:
561 | dependency: transitive
562 | description:
563 | name: test_api
564 | sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
565 | url: "https://pub.dev"
566 | source: hosted
567 | version: "0.4.16"
568 | typed_data:
569 | dependency: transitive
570 | description:
571 | name: typed_data
572 | sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
573 | url: "https://pub.dev"
574 | source: hosted
575 | version: "1.3.1"
576 | url_launcher:
577 | dependency: "direct main"
578 | description:
579 | name: url_launcher
580 | sha256: "75f2846facd11168d007529d6cd8fcb2b750186bea046af9711f10b907e1587e"
581 | url: "https://pub.dev"
582 | source: hosted
583 | version: "6.1.10"
584 | url_launcher_android:
585 | dependency: transitive
586 | description:
587 | name: url_launcher_android
588 | sha256: dd729390aa936bf1bdf5cd1bc7468ff340263f80a2c4f569416507667de8e3c8
589 | url: "https://pub.dev"
590 | source: hosted
591 | version: "6.0.26"
592 | url_launcher_ios:
593 | dependency: transitive
594 | description:
595 | name: url_launcher_ios
596 | sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2"
597 | url: "https://pub.dev"
598 | source: hosted
599 | version: "6.1.4"
600 | url_launcher_linux:
601 | dependency: transitive
602 | description:
603 | name: url_launcher_linux
604 | sha256: "206fb8334a700ef7754d6a9ed119e7349bc830448098f21a69bf1b4ed038cabc"
605 | url: "https://pub.dev"
606 | source: hosted
607 | version: "3.0.4"
608 | url_launcher_macos:
609 | dependency: transitive
610 | description:
611 | name: url_launcher_macos
612 | sha256: "0ef2b4f97942a16523e51256b799e9aa1843da6c60c55eefbfa9dbc2dcb8331a"
613 | url: "https://pub.dev"
614 | source: hosted
615 | version: "3.0.4"
616 | url_launcher_platform_interface:
617 | dependency: transitive
618 | description:
619 | name: url_launcher_platform_interface
620 | sha256: "6c9ca697a5ae218ce56cece69d46128169a58aa8653c1b01d26fcd4aad8c4370"
621 | url: "https://pub.dev"
622 | source: hosted
623 | version: "2.1.2"
624 | url_launcher_web:
625 | dependency: transitive
626 | description:
627 | name: url_launcher_web
628 | sha256: "81fe91b6c4f84f222d186a9d23c73157dc4c8e1c71489c4d08be1ad3b228f1aa"
629 | url: "https://pub.dev"
630 | source: hosted
631 | version: "2.0.16"
632 | url_launcher_windows:
633 | dependency: transitive
634 | description:
635 | name: url_launcher_windows
636 | sha256: a83ba3607a507758669cfafb03f9de09bf6e6280c14d9b9cb18f013e406dcacd
637 | url: "https://pub.dev"
638 | source: hosted
639 | version: "3.0.5"
640 | uuid:
641 | dependency: transitive
642 | description:
643 | name: uuid
644 | sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
645 | url: "https://pub.dev"
646 | source: hosted
647 | version: "3.0.7"
648 | vector_graphics:
649 | dependency: transitive
650 | description:
651 | name: vector_graphics
652 | sha256: "4cf8e60dbe4d3a693d37dff11255a172594c0793da542183cbfe7fe978ae4aaa"
653 | url: "https://pub.dev"
654 | source: hosted
655 | version: "1.1.4"
656 | vector_graphics_codec:
657 | dependency: transitive
658 | description:
659 | name: vector_graphics_codec
660 | sha256: "278ad5f816f58b1967396d1f78ced470e3e58c9fe4b27010102c0a595c764468"
661 | url: "https://pub.dev"
662 | source: hosted
663 | version: "1.1.4"
664 | vector_graphics_compiler:
665 | dependency: transitive
666 | description:
667 | name: vector_graphics_compiler
668 | sha256: "0bf61ad56e6fd6688a2865d3ceaea396bc6a0a90ea0d7ad5049b1b76c09d6163"
669 | url: "https://pub.dev"
670 | source: hosted
671 | version: "1.1.4"
672 | vector_math:
673 | dependency: transitive
674 | description:
675 | name: vector_math
676 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
677 | url: "https://pub.dev"
678 | source: hosted
679 | version: "2.1.4"
680 | win32:
681 | dependency: transitive
682 | description:
683 | name: win32
684 | sha256: a6f0236dbda0f63aa9a25ad1ff9a9d8a4eaaa5012da0dc59d21afdb1dc361ca4
685 | url: "https://pub.dev"
686 | source: hosted
687 | version: "3.1.4"
688 | xdg_directories:
689 | dependency: transitive
690 | description:
691 | name: xdg_directories
692 | sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1
693 | url: "https://pub.dev"
694 | source: hosted
695 | version: "1.0.0"
696 | xml:
697 | dependency: transitive
698 | description:
699 | name: xml
700 | sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5"
701 | url: "https://pub.dev"
702 | source: hosted
703 | version: "6.2.2"
704 | sdks:
705 | dart: ">=2.19.0-0 <3.0.0"
706 | flutter: ">=3.7.0-0"
707 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: chatgpt
2 | description: A new Flutter project.
3 |
4 | # The following line prevents the package from being accidentally published to
5 | # pub.dev using `flutter pub publish`. This is preferred for private packages.
6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev
7 |
8 | # The following defines the version and build number for your application.
9 | # A version number is three numbers separated by dots, like 1.2.43
10 | # followed by an optional build number separated by a +.
11 | # Both the version and the builder number may be overridden in flutter
12 | # build by specifying --build-name and --build-number, respectively.
13 | # In Android, build-name is used as versionName while build-number used as versionCode.
14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
16 | # Read more about iOS versioning at
17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
18 | # In Windows, build-name is used as the major, minor, and patch parts
19 | # of the product and file versions while build-number is used as the build suffix.
20 | version: 1.0.2+3
21 |
22 | environment:
23 | sdk: '>=2.18.6 <3.0.0'
24 |
25 | # Dependencies specify other packages that your package needs in order to work.
26 | # To automatically upgrade your package dependencies to the latest versions
27 | # consider running `flutter pub upgrade --major-versions`. Alternatively,
28 | # dependencies can be manually updated by changing the version numbers below to
29 | # the latest version available on pub.dev. To see which dependencies have newer
30 | # versions available, run `flutter pub outdated`.
31 | dependencies:
32 | animated_text_kit: ^4.2.2
33 | cached_network_image: ^3.2.3
34 | cupertino_icons: ^1.0.2
35 | dio: ^5.1.1
36 | flutter:
37 | sdk: flutter
38 | flutter_staggered_grid_view: ^0.6.2
39 | flutter_svg: ^2.0.4
40 | image_downloader: ^0.31.0
41 | logger: ^1.1.0
42 | lottie: ^2.1.0
43 | provider: ^6.0.5
44 | shared_preferences: ^2.0.15
45 | shimmer: ^2.0.0
46 | url_launcher: ^6.1.7
47 |
48 | dev_dependencies:
49 | flutter_lints: ^2.0.0
50 | flutter_test:
51 | sdk: flutter
52 |
53 | # For information on the generic Dart part of this file, see the
54 | # following page: https://dart.dev/tools/pub/pubspec
55 | # The following section is specific to Flutter packages.
56 | flutter:
57 |
58 | # The following line ensures that the Material Icons font is
59 | # included with your application, so that you can use the icons in
60 | # the material Icons class.
61 | uses-material-design: true
62 | # To add assets to your application, add an assets section, like this:
63 | assets:
64 | - assets/openai.svg
65 | - assets/Viki 2 AI.png
66 | # - images/a_dot_ham.jpeg
67 | # An image asset can refer to one or more resolution-specific "variants", see
68 | # https://flutter.dev/assets-and-images/#resolution-aware
69 | # For details regarding adding assets from package dependencies, see
70 | # https://flutter.dev/assets-and-images/#from-packages
71 | # To add custom fonts to your application, add a fonts section here,
72 | # in this "flutter" section. Each entry in this list should have a
73 | # "family" key with the font family name, and a "fonts" key with a
74 | # list giving the asset and other descriptors for the font. For
75 | # example:
76 | # fonts:
77 | # - family: Schyler
78 | # fonts:
79 | # - asset: fonts/Schyler-Regular.ttf
80 | # - asset: fonts/Schyler-Italic.ttf
81 | # style: italic
82 | # - family: Trajan Pro
83 | # fonts:
84 | # - asset: fonts/TrajanPro.ttf
85 | # - asset: fonts/TrajanPro_Bold.ttf
86 | # weight: 700
87 | #
88 | # For details regarding fonts from package dependencies,
89 | # see https://flutter.dev/custom-fonts/#from-packages
90 |
--------------------------------------------------------------------------------
/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility in the flutter_test package. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:chatgpt/main.dart';
12 |
13 | void main() {
14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(const MyApp());
17 |
18 | // Verify that our counter starts at 0.
19 | expect(find.text('0'), findsOneWidget);
20 | expect(find.text('1'), findsNothing);
21 |
22 | // Tap the '+' icon and trigger a frame.
23 | await tester.tap(find.byIcon(Icons.add));
24 | await tester.pump();
25 |
26 | // Verify that our counter has incremented.
27 | expect(find.text('0'), findsNothing);
28 | expect(find.text('1'), findsOneWidget);
29 | });
30 | }
31 |
--------------------------------------------------------------------------------
/update_version.json:
--------------------------------------------------------------------------------
1 | {
2 | "versionCode":2,
3 | "versionName":"1.0.0",
4 | "contentText":"Please update your app",
5 | "minSupport":2,
6 | "url":"https://github.com/VikramadityaDev/Viki-2-OpenAI/releases/download/v1.0.1/app-armeabi-v7a-release.apk"
7 | }
8 |
--------------------------------------------------------------------------------