Skip to content

Commit

Permalink
add chatbot gemini
Browse files Browse the repository at this point in the history
  • Loading branch information
shubhagarwal1 committed Nov 1, 2024
1 parent 2f5dca3 commit 30527d7
Show file tree
Hide file tree
Showing 5 changed files with 304 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { ContributorsComponent } from './components/contributors/contributors.co
import { CodeEditorComponent } from './components/code-editor/code-editor.component';
import { ReviewComponent } from './components/reviews/reviews.component';
import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component';

import { GeminibotComponent } from './components/geminibot/geminibot.component';

import { AlgorithmComparisonComponent } from './components/algocompare/algocompare.component';

Expand Down Expand Up @@ -92,6 +92,10 @@ export const routes: Routes = [
path: 'pagenotfound',
component: PageNotFoundComponent,
},
{
path: 'gemini',
component: GeminibotComponent,
},
// {
// path: 'algo-compare',
// component: AlgorithmComparisonComponent,
Expand Down
145 changes: 145 additions & 0 deletions src/app/components/geminibot/geminibot.component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/* geminibot.component.css */
.chat-container {
display: flex;
flex-direction: column;
height: 100vh;
background-color: #f5f5f5;
padding: 1rem;
}

.chat-header {
background-color: #ffffff;
padding: 1rem;
border-radius: 8px 8px 0 0;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.chat-header h1 {
margin: 0;
color: #333;
font-size: 1.5rem;
font-weight: 600;
}

.messages-container {
flex: 1;
overflow-y: auto;
padding: 1rem;
background-color: #ffffff;
margin: 1rem 0;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.message {
display: flex;
margin-bottom: 1rem;
}

.message-content {
max-width: 70%;
padding: 0.8rem 1rem;
border-radius: 12px;
position: relative;
}

.user-message {
justify-content: flex-end;
}

.user-message .message-content {
background-color: #1976d2;
color: white;
border-bottom-right-radius: 4px;
}

.bot-message .message-content {
background-color: #e9ecef;
color: #333;
border-bottom-left-radius: 4px;
}

.message-sender {
font-size: 0.8rem;
margin-top: 0.3rem;
opacity: 0.7;
}

.input-container {
background-color: #ffffff;
padding: 1rem;
border-radius: 0 0 8px 8px;
box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1);
}

.message-input {
width: 100%;
padding: 0.8rem;
border: 1px solid #dee2e6;
border-radius: 8px;
margin-bottom: 1rem;
resize: none;
min-height: 80px;
background-color: #f8f9fa;
}

.message-input:focus {
outline: none;
border-color: #1976d2;
box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.1);
}

.button-group {
display: flex;
gap: 1rem;
}

.send-button, .clear-button {
padding: 0.6rem 1.2rem;
border: none;
border-radius: 6px;
cursor: pointer;
font-weight: 500;
transition: background-color 0.2s;
}

.send-button {
background-color: #1976d2;
color: white;
}

.send-button:hover {
background-color: #1565c0;
}

.send-button:disabled {
background-color: #90caf9;
cursor: not-allowed;
}

.clear-button {
background-color: #e9ecef;
color: #495057;
}

.clear-button:hover {
background-color: #dee2e6;
}

/* Scrollbar styling */
.messages-container::-webkit-scrollbar {
width: 6px;
}

.messages-container::-webkit-scrollbar-track {
background: #f1f1f1;
}

.messages-container::-webkit-scrollbar-thumb {
background: #888;
border-radius: 3px;
}

.messages-container::-webkit-scrollbar-thumb:hover {
background: #666;
}
28 changes: 28 additions & 0 deletions src/app/components/geminibot/geminibot.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!-- geminibot.component.html -->
<div class="chat-container">
<div class="chat-header">
<h1>Gemini AI Chat</h1>
</div>

<div #chatContainerRef class="messages-container">
<div *ngFor="let msg of chatHistory"
[class]="msg.sender === 'User' ? 'message user-message' : 'message bot-message'">
<div class="message-content">
<span [innerHTML]="formatMessage(msg.text)"></span>
<div class="message-sender">{{ msg.sender }}</div>
</div>
</div>
</div>

<div class="input-container">
<textarea [(ngModel)]="userInput" placeholder="Type a message..." class="message-input"></textarea>
<div class="button-group">
<button (click)="getResponse()" [disabled]="!userInput" class="send-button">
Send
</button>
<button (click)="handleClearChat()" class="clear-button">
Clear
</button>
</div>
</div>
</div>
23 changes: 23 additions & 0 deletions src/app/components/geminibot/geminibot.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { GeminibotComponent } from './geminibot.component';

describe('GeminibotComponent', () => {
let component: GeminibotComponent;
let fixture: ComponentFixture<GeminibotComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [GeminibotComponent]
})
.compileComponents();

fixture = TestBed.createComponent(GeminibotComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
103 changes: 103 additions & 0 deletions src/app/components/geminibot/geminibot.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { Component, ElementRef, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { ToastrService } from 'ngx-toastr';

@Component({
selector: 'app-geminibot',
standalone: true,
imports: [FormsModule, CommonModule],
templateUrl: './geminibot.component.html',
styleUrls: ['./geminibot.component.css']
})
export class GeminibotComponent {
private geminiKey: string = 'AIzaSyC6OTnqrVONRR2PXSa5xPj_lwa-Dg2q2pw';
userInput: string = '';
chatHistory: Array<{ sender: string; text: string }> = [];

@ViewChild('chatContainerRef') chatContainerRef: ElementRef | null = null;

constructor(private http: HttpClient, private toastr: ToastrService) {
const savedHistory = localStorage.getItem('chatHistory');
this.chatHistory = savedHistory ? JSON.parse(savedHistory) : [];
}

ngOnInit() {
localStorage.setItem('chatHistory', JSON.stringify(this.chatHistory));
this.scrollToBottom();
}

formatMessage(text: string): string {
const messageText = typeof text === 'string' ? text : '';

// Replace newlines with <br> for line breaks
let formattedText = messageText.replace(/\n/g, '<br>');

// Bold formatting for text between "**"
formattedText = formattedText.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');

// List items starting with a digit (for numbered lists)
formattedText = formattedText.replace(/(\d\.\s)/g, '<br>&nbsp;&nbsp;$1');

// List items starting with a hyphen or asterisk
formattedText = formattedText.replace(/(\*\s|\-\s)/g, '<br>&nbsp;&nbsp;&bull; ');

return formattedText;
}

async getResponse() {
if (!this.userInput) return;

const userMessage = { sender: "User", text: this.userInput };
this.chatHistory.push(userMessage);
const userInput = this.userInput; // Store user input for the prompt
this.userInput = '';

try {
const res: any = await this.http.post(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key=${this.geminiKey}`,
{
contents: [
{
parts: [
{ text: "Previous Responses: " + this.chatHistory.map(msg => msg.text).join("\n") + "\nUser Query: " + userInput }
]
}
]
},
{ headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }
).toPromise();

// Extracting the bot response text
const botResponse = res?.candidates?.[0]?.content?.parts?.[0]?.text;

if (botResponse) {
const botMessage = { sender: "Gemini AI", text: botResponse };
this.chatHistory.push(botMessage);
} else {
this.toastr.error('Failed to fetch a response from Gemini AI.');
}
} catch (error) {
console.error('Error:', error);
this.toastr.error('An error occurred while fetching the response.');
} finally {
localStorage.setItem('chatHistory', JSON.stringify(this.chatHistory));
this.scrollToBottom();
}
}


handleClearChat() {
this.chatHistory = [];
localStorage.removeItem('chatHistory');
}

scrollToBottom() {
if (this.chatContainerRef?.nativeElement) {
this.chatContainerRef.nativeElement.scrollTop = this.chatContainerRef.nativeElement.scrollHeight;
}
}


}

0 comments on commit 30527d7

Please sign in to comment.