├── .env
├── .gitignore
├── LICENSE
├── README.md
├── __pycache__
└── app.cpython-312.pyc
├── app.py
├── requirements.txt
├── static
├── ai_bot.png
├── css
│ ├── image_text.css
│ ├── root.css
│ └── style.css
├── js
│ ├── additional.js
│ ├── app.js
│ └── image_chat.js
└── person_avatar.png
├── templates
├── chats.html
├── image_upload.html
└── index.html
└── vercel.json
/.env:
--------------------------------------------------------------------------------
1 | API_KEY= your api key
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | env
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Yash Kumar Saini
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 |
2 |
3 |
4 |
5 | ## Introduction
6 |
7 | Welcome to Gemini-Bot, your intelligent companion designed to revolutionize the way you interact with information. Leveraging the power of the Gemini AI platform, Gemini-Bot provides a seamless and intuitive interface for users to make both text and image queries. Whether you're looking for quick answers, detailed explanations, or visual insights, Gemini-Bot is here to assist you. With its advanced features like session storage and the use of the Fetch API for efficient server communication, Gemini-Bot ensures a smooth and engaging user experience. Get ready to explore a world of information at your fingertips with Gemini-Bot.
8 |
9 |
10 | ## Features
11 |
12 | 1. **Text and Image Queries**: Gemini-Bot allows users to make both text and image queries to the Gemini AI platform.
13 | 2. **Session Storage**: User queries and corresponding answers are stored in the sessionStorage, ensuring that chats are retained even after page reloads.
14 | 3. **Fetch API**: The Fetch API is used to send requests to the Flask server, enabling seamless communication without page reloads.
15 |
16 | ## Getting Started
17 |
18 | ### Requirements
19 |
20 | - Web browser (Chrome, Firefox, Safari, etc.)
21 | - Internet connection
22 |
23 | ### Installation
24 |
25 | 1. Clone the Gemini-Bot repository from GitHub.
26 | ```bash
27 | git clone https://github.com/yashksaini-coder/Gemini-Bot
28 | ```
29 | 2. Navigate to the Gemini-Bot directory.
30 | ```bash
31 | cd Gemini-Bot
32 | ```
33 | 3. Install the packages from requirements.txt
34 | ```bash
35 | pip install -r requirements.txt
36 | ```
37 | 4. Run `python app.py` from your preferred terminal.
38 |
39 | ### Usage
40 |
41 | 1. **Text Queries**:
42 | - Enter your text query in the text input field.
43 | - Press the "Send" button or hit Enter to submit the query.
44 | - View the response from the Gemini AI platform in the chat interface.
45 |
46 | 2. **Image Queries**:
47 | - Click the "Upload Image" button.
48 | - Select an image file from your device.
49 | - Enter your specific query for the image.
50 | - Wait for the response from the Gemini AI platform, which will be displayed in the chat interface.
51 |
52 | 3. **Session Storage**:
53 | - User queries and responses are stored in sessionStorage.
54 | - This ensures that chats are retained even if the page is reloaded or navigated away from.
55 |
56 | 4. **Fetch API**:
57 | - The Fetch API is used to send requests to the Flask server.
58 | - This communication method avoids page reloads, providing a smoother user experience.
59 |
60 | 3. **API Key**:
61 | - Please obtain your own API key from the Gemini AI platform at [https://ai.google.dev/](https://ai.google.dev/).
62 | - Replace the placeholder API key in the (`.env`) file with your own API key for proper functionality.
63 | # Contributing and Maintaining
64 |
65 | Thank you for your interest in contributing to the Gemini-Bot repository! Your contributions are highly appreciated. This document provides guidelines on how to contribute to the project and how to keep your fork up-to-date with the original repository.
66 |
67 | ## Contributing
68 |
69 | To contribute to the Gemini-Bot repository, please follow these steps:
70 |
71 | 1. **Fork the Repository**: Click on the [Fork](https://github.com/yashksaini-coder/Gemini-Bot/fork) button at the top right corner of the repository page. This will create a copy of the repository in your GitHub account.
72 |
73 | 2. **Clone the Repository**: Clone the forked repository to your local machine using the following command:
74 | ```bash
75 | git clone https://github.com/your-username/Gemini-Bot.git
76 | ```
77 | Replace `your-username` with your GitHub username.
78 |
79 | 3. **Create a New Branch**: Create a new branch for your changes using the following command:
80 | ```bash
81 | git checkout -b feature-branch-name
82 | ```
83 | Replace `feature-branch-name` with a descriptive name for your branch.
84 |
85 | 4. **Make Changes**: Make your desired changes to the codebase.
86 |
87 | 5. **Commit Changes**: Commit your changes using the following commands:
88 | ```bash
89 | git add .
90 | git commit -m "Describe your changes"
91 | ```
92 |
93 | 6. **Push Changes to GitHub**: Push your changes to your forked repository on GitHub using the following command:
94 | ```bash
95 | git push origin feature-branch-name
96 | ```
97 |
98 | 7. **Create a Pull Request**: Navigate to your forked repository on GitHub and click on the "Compare & pull request" button. Provide a descriptive title and detailed description of your changes, then submit the pull request.
99 |
100 | ## Keeping Your Fork Up-to-Date
101 |
102 | To keep your fork up-to-date with the original repository, follow these steps:
103 |
104 | 1. **Add the Original Repository as a Remote**: Add the original repository as a remote to your local repository using the following command:
105 | ```bash
106 | git remote add upstream https://github.com/yashksaini-coder/Gemini-Bot
107 | ```
108 |
109 | 2. **Fetch Updates from the Original Repository**: Fetch the latest updates from the original repository using the following command:
110 | ```bash
111 | git fetch upstream
112 | ```
113 |
114 | 3. **Merge Updates into Your Fork**: Switch to the main branch of your local repository and merge the updates from the original repository using the following commands:
115 | ```bash
116 | git checkout main
117 | git merge upstream/main
118 | ```
119 |
120 | 4. **Push Updates to Your GitHub Fork**: Push the updates to your forked repository on GitHub using the following command:
121 | ```bash
122 | git push origin main
123 | ```
124 | Thank you for your contributions and happy coding! 🚀
125 |
--------------------------------------------------------------------------------
/__pycache__/app.cpython-312.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yashksaini-coder/Gemini-Bot/ad983b79da0b261591b454b6136e86ad61aff645/__pycache__/app.cpython-312.pyc
--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------
1 | from flask import Flask, redirect, render_template, url_for, request, jsonify
2 | from dotenv import load_dotenv
3 | import google.generativeai as genai
4 | from PIL import Image
5 | import os
6 | from markdown import markdown
7 |
8 | load_dotenv('.env')
9 | genai.configure(api_key=os.getenv('API_KEY'))
10 |
11 | model = genai.GenerativeModel('gemini-pro')
12 | chat_model = model.start_chat(history=[]) # chat based on history
13 |
14 | img_model = genai.GenerativeModel('gemini-pro-vision')
15 |
16 | app = Flask(__name__)
17 |
18 |
19 | @app.route("/")
20 | def home():
21 | return render_template("index.html")
22 |
23 | # Text to text
24 |
25 |
26 | @app.route("/chat", methods=['GET', 'POST'])
27 | def chat():
28 | if request.method == 'POST':
29 | query = request.json['query']
30 | if (len(query.strip()) == 0):
31 | return jsonify("Please enter something!")
32 | try:
33 | gemini_response = chat_model.send_message(
34 | query).text # Send message based on the chat history
35 | except:
36 | return jsonify("Something went wrong!")
37 |
38 | return jsonify(markdown(gemini_response))
39 | else:
40 | return render_template("chats.html")
41 |
42 | # Image to text
43 |
44 |
45 | @app.route("/image_chat", methods=['POST', 'GET'])
46 | def image_chat():
47 | if request.method == 'POST':
48 | img = request.files['image'] # Loads the file
49 | q = request.form['query'] # Loads the query
50 |
51 | image = Image.open(img) # Read the image in PIL format
52 | try:
53 | response = img_model.generate_content(
54 | [q, image]) # Generate content for the image
55 | except: # noqa: E722
56 | return jsonify("Something went wrong!")
57 | return jsonify(markdown(response.text))
58 | else:
59 | return render_template("image_upload.html")
60 |
61 |
62 | if __name__ == "__main__":
63 | app.run(port=8080, debug=True)
64 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Flask==3.0.3
2 | Gunicorn
3 | Markdown==3.4.4
4 | google-generativeai==0.3.2
5 | Pillow==9.5.0
6 | protobuf
7 | python-dotenv==1.0.1
--------------------------------------------------------------------------------
/static/ai_bot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yashksaini-coder/Gemini-Bot/ad983b79da0b261591b454b6136e86ad61aff645/static/ai_bot.png
--------------------------------------------------------------------------------
/static/css/image_text.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Cabin:ital,wght@0,400..700;1,400..700&family=Mukta:wght@200;300;400;500;600;700;800&family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Nunito:ital,wght@0,200..1000;1,200..1000&family=Roboto+Condensed:ital,wght@0,100..900;1,100..900&family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap');
2 | input#image{
3 | display: none;
4 | }
5 | div.user img#query_img, div.user img#query_temp_img{
6 | margin-top: 0.8rem !important;
7 | height: 150px;
8 | border-radius: 10px !important;
9 | }
10 | div.user img#query_temp_img{
11 | margin-bottom: 1.5rem;
12 | }
13 | div#query_area button#submit, div#query_area label[for='image']{
14 | position: absolute;
15 | height: min-content;
16 | padding: 0 !important;
17 | background-color: rgb(255, 255, 255);
18 | display: flex;
19 | justify-content: center;
20 | align-items: center;
21 | margin-top: auto;
22 | margin-bottom: auto;
23 | outline: none;
24 | padding: 0.1rem 0.2rem !important;
25 | border: none;
26 | border-radius: 5px;
27 | cursor: pointer;
28 | z-index: 7;
29 | color: rgb(0, 0, 0);
30 | }
31 | div#query_area button#submit{
32 | right: 0.85rem
33 | }
34 | div#query_area label[for='image']{
35 | right: 3.3rem;
36 | }
37 | div.chat div.user p{
38 | margin-top: 0.3rem;
39 | }
40 | @media screen and (max-width: 640px) {
41 | div.user img#query_img, div.user img#query_temp_img{
42 | height: 120px;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/static/css/root.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Cabin:ital,wght@0,400..700;1,400..700&family=Mukta:wght@200;300;400;500;600;700;800&family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Nunito:ital,wght@0,200..1000;1,200..1000&family=Roboto+Condensed:ital,wght@0,100..900;1,100..900&family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap');
2 | *{
3 | padding: 0;
4 | margin: 0;
5 | }
6 | body{
7 | width: 100vw;
8 | min-height: 100vh;
9 | background-color: rgb(31, 31, 31);
10 | color: white;
11 | font-family: "Mulish", sans-serif;
12 | display: flex;
13 | justify-content: center;
14 | align-items: center;
15 | overflow-x: hidden;
16 | overflow-y: auto;
17 | }
18 | div.container{
19 | width: 50vw;
20 | min-height: 80vh;
21 | padding: 1rem;
22 | box-sizing: border-box;
23 | /* border: 1px solid rgba(255, 255, 255, 0.521);
24 | border-radius: 1rem; */
25 | display: flex;
26 | flex-direction: column;
27 | align-items: center;
28 | justify-content: space-around;
29 | gap: 1.5rem;
30 | }
31 | div.container div#logo_desc{
32 | display: flex;
33 | flex-direction: column;
34 | justify-content: center;
35 | align-items: center;
36 | /* outline: 2px solid green; */
37 | }
38 | div.container div#logo_desc p{
39 | margin-top: 1.2rem;
40 | font-size: 1.4rem;
41 | text-align: center;
42 | }
43 | div.container div#logo_desc p span{
44 | font-weight: 400;
45 | font-size: 1.8rem;
46 | background: #00FF00;
47 | background: linear-gradient(to left, #ad1ca6 0%, #00FFFF 100%);
48 | -webkit-background-clip: text;
49 | -webkit-text-fill-color: transparent;
50 | background-clip: text;
51 | text-decoration-color: transparent;
52 | }
53 |
54 | div.container div#logo_desc img{
55 | height: 13rem;
56 | width: 15rem;
57 | aspect-ratio: 1;
58 | }
59 |
60 | div.container div#links{
61 | width: 100%;
62 | height: 35%;
63 | display: flex;
64 | justify-content: space-evenly;
65 | align-items: center;
66 | flex-wrap: wrap;
67 | gap: 1.5rem;
68 | /* outline: 1px solid red; */
69 | }
70 | div.container div#links a{
71 | display: inline-flex;
72 | flex-direction: column;
73 | padding: 0.5rem 1rem;
74 | width: 13.5rem;
75 | aspect-ratio: 1.5/1;
76 | box-sizing: border-box;
77 | border-radius: 10px;
78 | color: white;
79 | text-decoration: none;
80 | justify-content: space-evenly;
81 | align-items: center;
82 | text-align: center;
83 | transition: all 0.15s ease-out;
84 | }
85 | div.container div#links a i{
86 | font-size: 3rem;
87 | }
88 | div.container div#links a:nth-child(1){
89 | background: #4776E6; /* fallback for old browsers */
90 | background: -webkit-linear-gradient(to right, #8E54E9, #4776E6); /* Chrome 10-25, Safari 5.1-6 */
91 | background: linear-gradient(to right, #8E54E9, #4776E6); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
92 |
93 | }
94 | div.container div#links a:nth-child(2){
95 | background: #ec008c; /* fallback for old browsers */
96 | background: -webkit-linear-gradient(to right, #fc6767, #ec008c); /* Chrome 10-25, Safari 5.1-6 */
97 | background: linear-gradient(to right, #fc6767, #ec008c); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
98 | }
99 | div.container div#links a:hover{
100 | transform: scale(0.95);
101 | }
102 |
103 | @media screen and (max-width: 640px) {
104 | div.container{
105 | width: 90vw !important;
106 | min-height: 85vh;
107 | flex-direction: column;
108 | justify-content: space-evenly;
109 | }
110 | div.container div#logo_desc img{
111 | height: 9rem;
112 | }
113 | div.container div#logo_desc p{
114 | font-size: 1rem;
115 | }
116 | div.container div#logo_desc p span{
117 | font-size: 1.2rem;
118 | }
119 | div.container div#links{
120 | flex-direction: column;
121 | gap: 1.5rem;
122 | }
123 | div.container div#links a{
124 | width: 66%;
125 | aspect-ratio: 1.6/1;
126 | }
127 | div.container div#links a i{
128 | font-size: 2rem;
129 | }
130 | }
--------------------------------------------------------------------------------
/static/css/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Cabin:ital,wght@0,400..700;1,400..700&family=Mukta:wght@200;300;400;500;600;700;800&family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Nunito:ital,wght@0,200..1000;1,200..1000&family=Roboto+Condensed:ital,wght@0,100..900;1,100..900&family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap');
2 | *{
3 | margin: 0;
4 | padding: 0;
5 | font-family: "Mulish", sans-serif;
6 | }
7 | body{
8 | width: 100vw;
9 | background-color: rgb(36, 36, 37);
10 | color: white;
11 | overflow-x: hidden;
12 | }
13 | header{
14 | width: 100vw;
15 | display: flex;
16 | justify-content: space-between;
17 | align-items: center;
18 | padding: 0.5rem;
19 | height: 3.5rem;
20 | font-size: 1.25rem;
21 | background-color: rgb(31, 31, 31);
22 | color: white;
23 | position: fixed;
24 | top: 0;
25 | z-index: 8;
26 | }
27 | header div#home{
28 | width: 2rem;
29 | margin-left: 1rem;
30 | position: absolute;
31 | top: auto;
32 | aspect-ratio: 1/1;
33 | z-index: 10;
34 | }
35 | header div#home a{
36 | width: 100%;
37 | height: 100%;
38 | font-size: 1.7rem;
39 | display: flex;
40 | justify-content: center;
41 | align-items: center;
42 | color: white;
43 | text-decoration: none;
44 | }
45 | header div#chat_options{
46 | width: 100%;
47 | /* outline: 1px solid red; */
48 | font-size: 1.1rem;
49 | display: flex;
50 | justify-content: center;
51 | align-items: center;
52 | position: relative;
53 | }
54 | div#chat_options p{
55 | display: flex;
56 | cursor: pointer;
57 | align-items: center;
58 | padding: 0.5rem 1rem;
59 | border-radius: 5px;
60 | border: 0.7px solid rgba(255, 255, 255, 0.511);
61 | background-color: rgb(44, 43, 43);
62 | }
63 | div#chat_options p:hover{
64 | background-color: rgb(36, 35, 35);
65 | }
66 | div#chat_options p i{
67 | margin-left: 0.5rem;
68 | font-size: 0.8rem;
69 | transition: all 0.12s ease-in;
70 | }
71 | div#chat_options ul{
72 | position: absolute;
73 | top: 2.8rem;
74 | border-radius: 5px;
75 | border: 0.7px solid rgba(255, 255, 255, 0.511);
76 | background-color: rgb(31, 31, 31);
77 | overflow: hidden;
78 | display: none;
79 | transition: all 0.2s ease-in;
80 | }
81 | div#chat_options ul li{
82 | list-style-type: none;
83 | }
84 | div#chat_options ul li a{
85 | display: block;
86 | padding: 0.5rem 2.3rem 0.5rem 0.8rem;
87 | color: white;
88 | text-decoration: none;
89 | }
90 | div#chat_options ul li a:hover{
91 | background-color: rgb(44, 43, 43);
92 | }
93 | div#query_area{
94 | display: flex;
95 | justify-content: center;
96 | position: fixed;
97 | background-color: rgb(31, 31, 31);
98 | bottom: 0;
99 | box-sizing: border-box;
100 | padding: 1rem;
101 | width: 100%;
102 | }
103 | div#query_area div.text_btn{
104 | width: 50%;
105 | display: flex;
106 | justify-content: center;
107 | align-items: center;
108 | position: relative;
109 | }
110 | div#query_area textarea{
111 | min-height: 2.2rem;
112 | padding: 0.75rem 0.7rem;
113 | border: 1px solid grey;
114 | /* overflow-y: auto; */
115 | border-radius: 10px;
116 | outline: none;
117 | font-size: 0.95rem;
118 | width: 100%;
119 | background-color: rgb(44, 43, 43);
120 | color: white;
121 | resize: none;
122 | }
123 | div#query_area button#submit{
124 | position: absolute;
125 | height: min-content;
126 | padding: 0 !important;
127 | background-color: rgb(255, 255, 255);
128 | display: flex;
129 | justify-content: center;
130 | align-items: center;
131 | margin-top: auto;
132 | margin-bottom: auto;
133 | outline: none;
134 | padding: 0.1rem 0.2rem !important;
135 | border: none;
136 | border-radius: 5px;
137 | cursor: pointer;
138 | color: rgb(0, 0, 0);
139 | right: 1rem;
140 | }
141 | div#query_area button#submit span{
142 | padding: 0 !important;
143 | }
144 | div.chats{
145 | margin: 6rem auto;
146 | width: 65vw;
147 | display: flex;
148 | flex-direction: column;
149 | }
150 |
151 | div.chats div.chat{
152 | margin-bottom: 1.35rem;
153 | }
154 | div.chat div.user{
155 | margin-bottom: 1.05rem;
156 | }
157 | div.chat div.user span, div.chat div.gemini span{
158 | font-weight: 700;
159 | }
160 | div.user div:nth-child(1), div.gemini div:nth-child(1){
161 | display: flex;
162 | align-items: center;
163 | gap: 10px;
164 | }
165 | div.user img.avatar, div.gemini img.avatar{
166 | height: 27px;
167 | aspect-ratio: 1;
168 | border-radius: 50%;
169 | background-color: rgb(28, 27, 27);
170 | outline: 0.1px solid rgba(255, 255, 255, 0.687);
171 | }
172 | div.chat div.user p, div.chat div.gemini p{
173 | margin-top: 0.5rem;
174 | }
175 | div.gemini p a{
176 | color: rgb(0, 119, 255);
177 | }
178 | div.gemini p a:hover{
179 | text-decoration: none;
180 | }
181 | div.chats div.chat h4:nth-child(2){
182 | margin-top: 0.5rem;
183 | }
184 | div.user p, div.gemini p{
185 | line-height: 1.5;
186 | }
187 | div#loading_div{
188 | display: flex;
189 | align-items: center;
190 | }
191 | span#loading{
192 | display: inline-block;
193 | width: 1rem;
194 | height: 1rem;
195 | border: 3px solid rgb(132, 132, 132);
196 | border-top: 3px solid white;
197 | animation: loading 0.35s linear infinite;
198 | border-radius: 50%;
199 | }
200 | @keyframes loading {
201 | from{
202 | transform: rotate(0);
203 | }to{
204 | transform: rotate(360deg);
205 | }
206 | }
207 | @media screen and (max-width: 640px){
208 | header{
209 | height: 3rem;
210 | }
211 | header div#home{
212 | margin-left: 0.5rem;
213 | }
214 | header div#home a{
215 | font-size: 1.5rem;
216 | }
217 | div#chat_options p{
218 | padding: 0.4rem 0.9rem;
219 | font-size: 1rem;
220 | }
221 | div#chat_options ul{
222 | font-size: 1rem;
223 | }
224 | div.chats{
225 | width: 75vw;
226 | margin: 5rem auto;
227 | }
228 |
229 | div#query_area{
230 | justify-content: center;
231 | bottom: -1px;
232 | }
233 | div#query_area textarea{
234 | padding: 0.5rem 0.7rem;
235 | }
236 | div#query_area div.text_btn{
237 | width: 90%;
238 | }
239 | }
--------------------------------------------------------------------------------
/static/js/additional.js:
--------------------------------------------------------------------------------
1 | let chat_options = document.getElementById("selected_option")
2 | let options = document.getElementById("options")
3 | let down_arrow = document.querySelector("div#chat_options p i")
4 |
5 | chat_options.addEventListener("click", () => {
6 | if (chat_options.classList.contains("opened")) {
7 | options.style.display = "none";
8 | down_arrow.style.transform = "rotate(0)"
9 | } else {
10 | options.style.display = "block";
11 | down_arrow.style.transform = "rotate(-180deg)"
12 | }
13 | chat_options.classList.toggle("opened")
14 | })
15 |
--------------------------------------------------------------------------------
/static/js/app.js:
--------------------------------------------------------------------------------
1 | let text_area = document.querySelector('textarea')
2 | let all_chats = document.querySelector('div.chats')
3 | let ask_btn = document.querySelector('button#submit')
4 |
5 | // Get response via fetch from the server
6 | async function get_response(query) {
7 | let response = await fetch("/chat", {
8 | headers: {
9 | 'Content-type': 'application/json'
10 | },
11 | method: 'POST',
12 | body: JSON.stringify({ query })
13 | })
14 | return response.json()
15 | }
16 |
17 | ask_btn.addEventListener("click", async () => {
18 |
19 | let query = text_area.value;
20 | text_area.value = ""
21 | ask_btn.disabled = true
22 | ask_btn.firstElementChild.style.opacity = "0.8"
23 | let new_query = document.createElement('div')
24 | new_query.setAttribute("class", "chat")
25 |
26 | // User part
27 | let user_query = document.createElement('div')
28 | user_query.setAttribute('class', 'user')
29 | let user_avatar_div = document.createElement('div')
30 | user_avatar_div.innerHTML = `You`
31 | let user_question = document.createElement('p')
32 | user_question.innerText = query
33 | user_query.append(user_avatar_div, user_question)
34 |
35 | // Gemini-Bot/Gemini part
36 | let gemini_response = document.createElement('div')
37 | gemini_response.setAttribute('class', 'gemini')
38 | let gemini_avatar_div = document.createElement('div')
39 | gemini_avatar_div.innerHTML = `Gemini-Bot`
40 | let gemini_ans = document.createElement('p')
41 | gemini_ans.innerHTML = "
Generating your content
"
42 | gemini_response.append(gemini_avatar_div, gemini_ans)
43 |
44 | new_query.append(user_query)
45 | new_query.append(gemini_response)
46 | all_chats.append(new_query)
47 |
48 | gemini_ans.innerHTML = await get_response(query)
49 | text_area.value = ""
50 | ask_btn.disabled = false
51 | ask_btn.firstElementChild.style.opacity = "1"
52 |
53 | // To retrieve all the items after refresh, using sessionStorage to store them
54 | // Using array to maintain the order of the chats
55 | setTimeout(() => {
56 | // query_array_7_48 contains all the chats
57 | // if query_array_7_48 is present, get it & push the new query
58 | // else create query_array_7_48 with the first query
59 | if (sessionStorage.getItem("query_array_7_48")) {
60 | let queries = JSON.parse(sessionStorage.getItem("query_array_7_48"))
61 | queries.push(new_query.outerHTML)
62 | sessionStorage.setItem("query_array_7_48", JSON.stringify(queries))
63 | } else {
64 | sessionStorage.setItem("query_array_7_48", JSON.stringify([new_query.outerHTML]))
65 | }
66 | }, 0) // This part is important to block this line execution upto all the synchronous part is executed
67 |
68 | })
69 |
70 | text_area.addEventListener("keydown", (event) => {
71 | if (event.key == 'Enter') {
72 | ask_btn.click()
73 | }
74 | })
75 |
76 | window.addEventListener("load", () => {
77 | let whole_html = ""
78 |
79 | // retrieve the array and take all the queries that was stored, then use it
80 | if (sessionStorage.getItem("query_array_7_48")) {
81 | let queries = JSON.parse(sessionStorage.getItem("query_array_7_48"))
82 | for (query of queries) {
83 | whole_html += query
84 | }
85 | }
86 | all_chats.innerHTML = whole_html
87 |
88 | })
--------------------------------------------------------------------------------
/static/js/image_chat.js:
--------------------------------------------------------------------------------
1 | let image = document.getElementById("image")
2 | let image_label = document.querySelector("label[for='image']")
3 | let text_area = document.querySelector('textarea')
4 | let ask_btn = document.querySelector('button#submit')
5 | let all_chats = document.querySelector('div.chats')
6 |
7 | var imgUrl = null;
8 | var loadedImg = null;
9 |
10 | // To send a fetch request to the server at specific endpoint
11 | async function get_response(data) {
12 |
13 | let response = await fetch("/image_chat", {
14 | method: 'POST',
15 | body: data
16 | })
17 | return response.json()
18 | }
19 |
20 | ask_btn.addEventListener("click", async function () {
21 | if (imgUrl) {
22 | // Remove the temp image div
23 | try {
24 | document.getElementById("temp-user-query").remove()
25 | } catch (err) {
26 |
27 | }
28 |
29 | let query = text_area.value;
30 | text_area.value = ""
31 |
32 | const formData = new FormData();
33 | formData.append('image', loadedImg); // using the last successfully loaded image that was created during input event
34 | formData.append('query', query);
35 |
36 | ask_btn.firstElementChild.style.opacity = "0.8"
37 | ask_btn.disabled = true
38 | ask_btn.style.cursor = 'not-allowed'
39 |
40 | image_label.firstElementChild.style.opacity = "0.8"
41 | image_label.disabled = true
42 | image_label.style.cursor = 'not-allowed'
43 |
44 | let new_query = document.createElement('div')
45 | new_query.setAttribute("class", "chat")
46 |
47 | // User part
48 | let user_query = document.createElement('div')
49 | user_query.setAttribute('class', 'user')
50 | let user_avatar_div = document.createElement('div')
51 | user_avatar_div.innerHTML = `You`
52 | let user_img_query = document.createElement('img')
53 | user_img_query.setAttribute('id', "query_img")
54 | user_img_query.src = `${imgUrl}` // using the image url that was created during input event
55 | let user_question = document.createElement('p')
56 | user_question.innerText = query
57 | user_query.append(user_avatar_div, user_img_query, user_question)
58 |
59 | // Gemini-Bot/Gemini part
60 | let gemini_response = document.createElement('div')
61 | gemini_response.setAttribute('class', 'gemini')
62 | let gemini_avatar_div = document.createElement('div')
63 | gemini_avatar_div.innerHTML = `Gemini-Bot`
64 | let gemini_ans = document.createElement('p')
65 | gemini_ans.innerHTML = "
Generating your content
"
66 | gemini_response.append(gemini_avatar_div, gemini_ans)
67 |
68 | // Creating new_query
69 | new_query.append(user_query)
70 | new_query.append(gemini_response)
71 |
72 | // Appending the new queries in to chats
73 | all_chats.append(new_query)
74 |
75 | gemini_ans.innerHTML = await get_response(formData)
76 | text_area.value = ""
77 |
78 | ask_btn.firstElementChild.style.opacity = "1"
79 | ask_btn.disabled = false
80 | ask_btn.style.cursor = 'pointer'
81 |
82 | image_label.firstElementChild.style.opacity = "1"
83 | image_label.disabled = false
84 | image_label.style.cursor = 'pointer'
85 |
86 | imgUrl = null; // remove the previous picture once it has been queried
87 |
88 | // To retrieve all the items after refresh, using sessionStorage to store them
89 | // Using array to maintain the order of the chats
90 | setTimeout(() => {
91 | // query_array_7_48 contains all the chats
92 | // if query_array_7_48 is present, get it & push the new query
93 | // else create query_array_7_48 with the first query
94 | if (sessionStorage.getItem("query_img_array_7_48")) {
95 | let queries = JSON.parse(sessionStorage.getItem("query_img_array_7_48"))
96 | queries.push(new_query.outerHTML)
97 | sessionStorage.setItem("query_img_array_7_48", JSON.stringify(queries))
98 | } else {
99 | sessionStorage.setItem("query_img_array_7_48", JSON.stringify([new_query.outerHTML]))
100 | }
101 | }, 0) // This part is important to block this line execution upto all the synchronous part is executed
102 | } else {
103 | alert("Please upload an image!")
104 | }
105 | })
106 |
107 | // Show the image when the user uploads it (temporarily)
108 | image.addEventListener("change", () => {
109 |
110 | try {
111 | let img = image.files[0]
112 | let img_url = URL.createObjectURL(img) // may throw error if the image is not uploaded
113 |
114 | loadedImg = img;
115 | imgUrl = img_url;
116 | try {
117 | document.getElementById("temp-user-query").remove()
118 | } catch (err) {
119 |
120 | }
121 | let user_query = document.createElement('div')
122 | user_query.setAttribute('class', 'user')
123 | user_query.setAttribute('id', 'temp-user-query')
124 | let user_avatar_div = document.createElement('div')
125 | user_avatar_div.innerHTML = `You`
126 | let user_img_query = document.createElement('img')
127 | user_img_query.setAttribute('id', "query_temp_img")
128 | user_img_query.src = `${img_url}`
129 | user_img_query.style.opacity = "0.8"
130 | user_query.append(user_avatar_div, user_img_query)
131 |
132 | all_chats.append(user_query)
133 | } catch (err) {
134 | console.log(err)
135 | imgUrl = null;
136 | }
137 | })
138 |
139 | text_area.addEventListener("keydown", (event) => {
140 | if (event.key == 'Enter') {
141 | ask_btn.click()
142 | }
143 | })
144 |
145 | // Function to load/retain all the chats when the page is refreshed/loaded
146 | window.addEventListener("load", () => {
147 | let whole_html = ""
148 | // retrieve the array and take all the queries that was stored, then use it
149 | if (sessionStorage.getItem("query_img_array_7_48")) {
150 | let queries = JSON.parse(sessionStorage.getItem("query_img_array_7_48"))
151 | for (query of queries) {
152 | whole_html += query
153 | }
154 | }
155 | all_chats.innerHTML = whole_html
156 | })
--------------------------------------------------------------------------------
/static/person_avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yashksaini-coder/Gemini-Bot/ad983b79da0b261591b454b6136e86ad61aff645/static/person_avatar.png
--------------------------------------------------------------------------------
/templates/chats.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Text to text
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |