-
Notifications
You must be signed in to change notification settings - Fork 0
feat(chat-receipe) Add receipe #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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" | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| 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), | ||
| }, | ||
| ]; | ||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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({ | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| export const environment = { | ||
| production: false, | ||
| googleAiKey: "" | ||
| } | ||
| production: false, | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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: '', | ||
| }; | ||
| 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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| .chat-container { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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); | ||
| } | ||
| } | ||
| 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; | ||
| } | ||
| } |
| 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', | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
|
|
||
|
|
@@ -18,12 +16,12 @@ export class GeminiGoogleAiService { | |
| /** | ||
| * Communicate with Gemini - Google Ai using text prompt | ||
| */ | ||
| askGemini(prompt: string): Observable<string> { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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(); | ||
| } | ||
| } | ||
| 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; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this extra ,