Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Angular/.prettier.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"semi": true,
"bracketSpacing": true,
"trailingComma": "es5",
"printWidth": 80,
"endOfLine": "If"
}
16 changes: 16 additions & 0 deletions Angular/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"prettier": "^3.3.3",
"typescript": "~5.5.2"
}
}
14 changes: 10 additions & 4 deletions Angular/src/app/app.routes.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { Routes } from '@angular/router';

export const routes: Routes = [
{
path: '',
loadComponent: () => import('../components/text-based-gemini/text-based-gemini.component').then(c => c.TextBasedGeminiComponent)
}
{
path: '',
redirectTo: 'chat',
pathMatch: 'full',
},
{
path: 'chat',
loadComponent: () =>
import('../pages/chat/chat.component').then((c) => c.ChatComponent),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this extra ,

},
];

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,35 @@ import { Subscription } from 'rxjs';
standalone: true,
imports: [],
templateUrl: './text-based-gemini.component.html',
styleUrl: './text-based-gemini.component.scss'
styleUrl: './text-based-gemini.component.scss',
})
export class TextBasedGeminiComponent implements OnInit, OnDestroy {
private subscription: Subscription | null = null;

constructor(
private genAiService: GeminiGoogleAiService
) { }
constructor(private genAiService: GeminiGoogleAiService) {}

ngOnInit(): void {
this.askGemini('Hey, How are you doing today?');
}

/**
* Communication with Gemini using Frontend Compatible Service
* @param text
* @param text
*/
askGemini(text: string) {
this.subscription = this.genAiService.askGemini(text).subscribe({
next: (response: string) => {
console.log(response);
alert(`Response from Gemini: ${response}`);
},
error: (error: any) => {
console.error('Error:', error);
alert('An error occurred while fetching the response from Gemini.');
},
complete: () => {
console.log('Gemini response completed successfully.');
}
});
// this.subscription = this.genAiService.askGemini(text).subscribe({
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented this out for the time being, as we might get rid of that. The service is the most important part.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what i think is, Rather than commenting whole code just remove the ngOnInit call to that function statement.

// next: (response: string) => {
// console.log(response);
// alert(`Response from Gemini: ${response}`);
// },
// error: (error: any) => {
// console.error('Error:', error);
// alert('An error occurred while fetching the response from Gemini.');
// },
// complete: () => {
// console.log('Gemini response completed successfully.');
// }
// });
}

ngOnDestroy(): void {
Expand Down
6 changes: 3 additions & 3 deletions Angular/src/environments/environment.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const environment = {
production: false,
googleAiKey: ""
}
production: false,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

linting is applied everywhere. please be commit the changes only related to you exactly. i saw many places, spaces updates.

googleAiKey: '',
};
21 changes: 21 additions & 0 deletions Angular/src/pages/chat/chat.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<div class="chat-container">
<div class="messages">
<div
*ngFor="let msg of messages"
[ngClass]="msg.isUser ? 'user-message' : 'bot-message'"
>
{{ msg.text }}
</div>
<div *ngIf="isLoading" class="loader"></div>
</div>
<form (submit)="onSubmit()" class="input-form">
<input
type="text"
[(ngModel)]="userInput"
(keyup.enter)="onSubmit()"
placeholder="Type your message here..."
name="chatInput"
required
/>
</form>
</div>
75 changes: 75 additions & 0 deletions Angular/src/pages/chat/chat.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
.chat-container {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what i think is we shouldn't add more time writing CSS here, let's just consume Bootstrap. more simple and fast.

display: flex;
flex-direction: column;
height: 100%;
max-width: 600px;
margin: 0 auto;
border: 1px solid #ddd;
border-radius: 8px;
}

.messages {
flex: 1;
overflow-y: auto;
padding: 10px;
}

.user-message,
.bot-message {
padding: 8px 12px;
border-radius: 8px;
margin-bottom: 10px;
word-wrap: break-word;
}

.user-message {
margin-left: auto;
align-self: flex-end;
width: fit-content;
background-color: #cce7ff;
text-align: right;
}

.bot-message {
width: 80%;
align-self: flex-start;
background-color: #f0f0f0;
text-align: left;
}

.input-form {
display: flex;
border-top: 1px solid #ddd;
padding: 10px;
}

input {
flex: 1;
padding: 12px;
font-size: 1rem;
border: none;
outline: none;
color: #ffffff;
background-color: #333333;
border-radius: 20px;
}

/* Loader styles */
.loader {
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
width: 24px;
height: 24px;
animation: spin 1s linear infinite;
margin: 10px auto;
}

@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
37 changes: 37 additions & 0 deletions Angular/src/pages/chat/chat.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { GeminiGoogleAiService } from '../../services/gemini-google-ai/gemini-google-ai.service';
import { CommonModule } from '@angular/common';

@Component({
selector: 'app-chat',
standalone: true,
imports: [FormsModule, CommonModule],
templateUrl: './chat.component.html',
styleUrls: ['./chat.component.scss'],
})
export class ChatComponent {
messages: { text: string; isUser: boolean }[] = [];
userInput: string = '';
isLoading: boolean = false;

constructor(private geminiService: GeminiGoogleAiService) {}

async onSubmit() {
if (!this.userInput.trim()) return;

this.isLoading = true;

this.messages.push({ text: this.userInput, isUser: true });

const userMessage = this.userInput;
this.userInput = '';

// TODO: Handle errors
const response = await this.geminiService.askGemini(userMessage);
this.messages.push({ text: response, isUser: false });

this.isLoading = false;
}
}
18 changes: 8 additions & 10 deletions Angular/src/services/gemini-google-ai/gemini-google-ai.service.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { Injectable } from '@angular/core';
import { GoogleGenerativeAI } from '@google/generative-ai';
import { GenerativeModel, GoogleGenerativeAI } from '@google/generative-ai';
import { environment } from '../../environments/environment';
import { asyncScheduler, from, map, Observable, of, scheduled } from 'rxjs';

@Injectable({
providedIn: 'root'
providedIn: 'root',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

linting issue, added extra comma, however it's not required.

})
export class GeminiGoogleAiService {

// instance to initiate Gemini - Google Ai with API_KEY
private genAI: GoogleGenerativeAI;

Expand All @@ -18,12 +16,12 @@ export class GeminiGoogleAiService {
/**
* Communicate with Gemini - Google Ai using text prompt
*/
askGemini(prompt: string): Observable<string> {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please fix linting issues

const model: any = this.genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
async askGemini(prompt: string): Promise<string> {
const model: GenerativeModel = this.genAI.getGenerativeModel({
model: 'gemini-1.5-flash',
});

// converting Promise to Observable - latest way "After Deprecation"
return scheduled(from(model.generateContent(prompt)), asyncScheduler).pipe(
map((result: any) => result.response.text())
);
const content = await model.generateContent(prompt);
return content.response.text();
}
}
5 changes: 4 additions & 1 deletion Angular/src/styles.scss
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
/* You can add global styles to this file, and also import other style files */
body {
font-size: 14px;
font-family: Verdana, Geneva, Tahoma, sans-serif;
}