Skip to content

Commit 6fb0dd7

Browse files
committed
update
1 parent 270555f commit 6fb0dd7

8 files changed

Lines changed: 248 additions & 102 deletions

File tree

documentation/components/MusicComponent.html

Lines changed: 195 additions & 59 deletions
Large diffs are not rendered by default.

documentation/coverage.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@
589589
<td>MusicComponent</td>
590590
<td align="right" data-sort="96">
591591
<span class="coverage-percent">96 %</span>
592-
<span class="coverage-count">(28/29)</span>
592+
<span class="coverage-count">(30/31)</span>
593593
</td>
594594
</tr>
595595
<tr class="very-good">

documentation/injectables/SaavnService.html

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -164,15 +164,15 @@ <h6><b>Properties</b></h6>
164164
<ul class="index-list">
165165
<li>
166166
<span class="modifier">Private</span>
167-
<a href="#apiUrl" >apiUrl</a>
167+
<a href="#geminiApiUrl" >geminiApiUrl</a>
168168
</li>
169169
<li>
170170
<span class="modifier">Private</span>
171-
<a href="#baseUrl" >baseUrl</a>
171+
<a href="#history" >history</a>
172172
</li>
173173
<li>
174174
<span class="modifier">Private</span>
175-
<a href="#history" >history</a>
175+
<a href="#savvanApiUrl" >savvanApiUrl</a>
176176
</li>
177177
</ul>
178178
</td>
@@ -491,11 +491,11 @@ <h3 id="inputs">
491491
<tbody>
492492
<tr>
493493
<td class="col-md-4">
494-
<a name="apiUrl"></a>
494+
<a name="geminiApiUrl"></a>
495495
<span class="name">
496496
<span class="modifier">Private</span>
497-
<span ><b>apiUrl</b></span>
498-
<a href="#apiUrl"><span class="icon ion-ios-link"></span></a>
497+
<span ><b>geminiApiUrl</b></span>
498+
<a href="#geminiApiUrl"><span class="icon ion-ios-link"></span></a>
499499
</span>
500500
</td>
501501
</tr>
@@ -523,34 +523,34 @@ <h3 id="inputs">
523523
<tbody>
524524
<tr>
525525
<td class="col-md-4">
526-
<a name="baseUrl"></a>
526+
<a name="history"></a>
527527
<span class="name">
528528
<span class="modifier">Private</span>
529-
<span ><b>baseUrl</b></span>
530-
<a href="#baseUrl"><span class="icon ion-ios-link"></span></a>
529+
<span ><b>history</b></span>
530+
<a href="#history"><span class="icon ion-ios-link"></span></a>
531531
</span>
532532
</td>
533533
</tr>
534534
<tr>
535535
<td class="col-md-4">
536-
<i>Type : </i> <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/string" target="_blank" >string</a></code>
536+
<i>Type : </i> <code><a href="../interfaces/ChatMessage.html" target="_self" >ChatMessage[]</a></code>
537537

538538
</td>
539539
</tr>
540540
<tr>
541541
<td class="col-md-4">
542-
<i>Default value : </i><code>&#x27;https://saavn.dev/api/search/songs&#x27;</code>
542+
<i>Default value : </i><code>[]</code>
543543
</td>
544544
</tr>
545545
<tr>
546546
<td class="col-md-4">
547-
<div class="io-line">Defined in <a href="" data-line="39" class="link-to-prism">src/app/service/saavan-api/saavan.service.ts:39</a></div>
547+
<div class="io-line">Defined in <a href="" data-line="34" class="link-to-prism">src/app/service/saavan-api/saavan.service.ts:34</a></div>
548548
</td>
549549
</tr>
550550

551551
<tr>
552552
<td class="col-md-4">
553-
<div class="io-description"><p>Base URL for Saavn song search API.</p>
553+
<div class="io-description"><p>Conversation history between user and AI model.</p>
554554
</div>
555555
</td>
556556
</tr>
@@ -561,34 +561,34 @@ <h3 id="inputs">
561561
<tbody>
562562
<tr>
563563
<td class="col-md-4">
564-
<a name="history"></a>
564+
<a name="savvanApiUrl"></a>
565565
<span class="name">
566566
<span class="modifier">Private</span>
567-
<span ><b>history</b></span>
568-
<a href="#history"><span class="icon ion-ios-link"></span></a>
567+
<span ><b>savvanApiUrl</b></span>
568+
<a href="#savvanApiUrl"><span class="icon ion-ios-link"></span></a>
569569
</span>
570570
</td>
571571
</tr>
572572
<tr>
573573
<td class="col-md-4">
574-
<i>Type : </i> <code><a href="../interfaces/ChatMessage.html" target="_self" >ChatMessage[]</a></code>
574+
<i>Type : </i> <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/string" target="_blank" >string</a></code>
575575

576576
</td>
577577
</tr>
578578
<tr>
579579
<td class="col-md-4">
580-
<i>Default value : </i><code>[]</code>
580+
<i>Default value : </i><code>&#x27;https://saavn.dev/api/search/songs&#x27;</code>
581581
</td>
582582
</tr>
583583
<tr>
584584
<td class="col-md-4">
585-
<div class="io-line">Defined in <a href="" data-line="34" class="link-to-prism">src/app/service/saavan-api/saavan.service.ts:34</a></div>
585+
<div class="io-line">Defined in <a href="" data-line="39" class="link-to-prism">src/app/service/saavan-api/saavan.service.ts:39</a></div>
586586
</td>
587587
</tr>
588588

589589
<tr>
590590
<td class="col-md-4">
591-
<div class="io-description"><p>Conversation history between user and AI model.</p>
591+
<div class="io-description"><p>Base URL for Saavn song search API.</p>
592592
</div>
593593
</td>
594594
</tr>
@@ -639,12 +639,12 @@ <h3 id="inputs">
639639
/**
640640
* Base URL for Saavn song search API.
641641
*/
642-
private baseUrl &#x3D; &#x27;https://saavn.dev/api/search/songs&#x27;;
642+
private savvanApiUrl &#x3D; &#x27;https://saavn.dev/api/search/songs&#x27;;
643643

644644
/**
645645
* Gemini API URL with authentication key from environment.
646646
*/
647-
private apiUrl &#x3D; &#x60;https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key&#x3D;${environment.geminiApiKey}&#x60;;
647+
private geminiApiUrl &#x3D; &#x60;https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key&#x3D;${environment.geminiApiKey}&#x60;;
648648

649649
/**
650650
* Creates an instance of SaavnService.
@@ -655,7 +655,7 @@ <h3 id="inputs">
655655
constructor(
656656
private http: HttpClient,
657657
private globalLoaderService: GlobalLoaderService
658-
) {}
658+
) { }
659659

660660
/**
661661
* Searches for songs using the Saavn API.
@@ -666,7 +666,7 @@ <h3 id="inputs">
666666
searchSongs(query: string) {
667667
this.globalLoaderService.show(&quot;Searching songs...&quot;);
668668

669-
return this.http.get&lt;any&gt;(&#x60;${this.baseUrl}?query&#x3D;${query}&amp;limit&#x3D;10&amp;page&#x3D;0&#x60;).pipe(
669+
return this.http.get&lt;any&gt;(&#x60;${this.savvanApiUrl}?query&#x3D;${query}&amp;limit&#x3D;10&amp;page&#x3D;0&#x60;).pipe(
670670
finalize(() &#x3D;&gt; {
671671
this.globalLoaderService.hide();
672672
})
@@ -736,7 +736,7 @@ <h3 id="inputs">
736736
const body &#x3D; { contents: this.history };
737737

738738
try {
739-
const res: any &#x3D; await firstValueFrom(this.http.post(this.apiUrl, body, { headers }));
739+
const res: any &#x3D; await firstValueFrom(this.http.post(this.geminiApiUrl, body, { headers }));
740740
const parts &#x3D; res?.candidates?.[0]?.content?.parts;
741741
const modelReply &#x3D; parts?.map((p: any) &#x3D;&gt; p.text).join(&#x27;\n\n&#x27;) || &#x27;No response&#x27;;
742742

documentation/interfaces/ChatMessage.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,12 +310,12 @@ <h3 id="inputs">Properties</h3>
310310
/**
311311
* Base URL for Saavn song search API.
312312
*/
313-
private baseUrl &#x3D; &#x27;https://saavn.dev/api/search/songs&#x27;;
313+
private savvanApiUrl &#x3D; &#x27;https://saavn.dev/api/search/songs&#x27;;
314314

315315
/**
316316
* Gemini API URL with authentication key from environment.
317317
*/
318-
private apiUrl &#x3D; &#x60;https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key&#x3D;${environment.geminiApiKey}&#x60;;
318+
private geminiApiUrl &#x3D; &#x60;https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key&#x3D;${environment.geminiApiKey}&#x60;;
319319

320320
/**
321321
* Creates an instance of SaavnService.
@@ -326,7 +326,7 @@ <h3 id="inputs">Properties</h3>
326326
constructor(
327327
private http: HttpClient,
328328
private globalLoaderService: GlobalLoaderService
329-
) {}
329+
) { }
330330

331331
/**
332332
* Searches for songs using the Saavn API.
@@ -337,7 +337,7 @@ <h3 id="inputs">Properties</h3>
337337
searchSongs(query: string) {
338338
this.globalLoaderService.show(&quot;Searching songs...&quot;);
339339

340-
return this.http.get&lt;any&gt;(&#x60;${this.baseUrl}?query&#x3D;${query}&amp;limit&#x3D;10&amp;page&#x3D;0&#x60;).pipe(
340+
return this.http.get&lt;any&gt;(&#x60;${this.savvanApiUrl}?query&#x3D;${query}&amp;limit&#x3D;10&amp;page&#x3D;0&#x60;).pipe(
341341
finalize(() &#x3D;&gt; {
342342
this.globalLoaderService.hide();
343343
})
@@ -407,7 +407,7 @@ <h3 id="inputs">Properties</h3>
407407
const body &#x3D; { contents: this.history };
408408

409409
try {
410-
const res: any &#x3D; await firstValueFrom(this.http.post(this.apiUrl, body, { headers }));
410+
const res: any &#x3D; await firstValueFrom(this.http.post(this.geminiApiUrl, body, { headers }));
411411
const parts &#x3D; res?.candidates?.[0]?.content?.parts;
412412
const modelReply &#x3D; parts?.map((p: any) &#x3D;&gt; p.text).join(&#x27;\n\n&#x27;) || &#x27;No response&#x27;;
413413

documentation/js/search/search_index.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/features/music/music.component.html

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<!-- Sticky Search Input -->
33
<div class="sticky py-4 px-2 top-0 z-10 bg-[var(--color-bg)]">
44
<div class="flex items-center gap-2">
5-
<input type="text" [(ngModel)]="query" (keyup.enter)="searchSong()" placeholder="Enter song name"
5+
<input #searchSongInput type="text" [(ngModel)]="query" (keyup.enter)="searchSong()" placeholder="Enter song name"
66
class="flex-1 p-2 rounded-md bg-[var(--input-bg)] text-[var(--input-text)] border border-[var(--input-border)] focus:outline-none focus:ring-2 focus:ring-[var(--theme-color)] transition" />
77
<button (click)="searchSong()"
88
class="bg-[var(--theme-color)] text-[var(--color-white)] px-4 py-2 rounded-md shadow hover:shadow-md active:scale-95 transition">Search</button>
@@ -11,9 +11,8 @@
1111

1212
<!-- Songs List -->
1313
<div *ngFor="let song of songs()"
14-
class="flex items-center gap-4 py-4 px-2 rounded-md hover:bg-[var(--list-hover)] transition-all cursor-pointer"
15-
(click)="playSong(getSongUrl(song), song)">
16-
<div class="relative w-12 h-12 rounded-md overflow-hidden group">
14+
class="flex items-center gap-4 py-4 px-2 rounded-md hover:bg-[var(--list-hover)] transition-all cursor-pointer">
15+
<div class="relative w-12 h-12 rounded-md overflow-hidden group" (click)="playSong(getSongUrl(song), song, true)">
1716
<img [src]="song.image?.[2]?.url || 'assets/img/music_icon/icons8-airpods-pro-max-100.png'" alt="{{ song.name }}"
1817
class="w-full h-full object-cover group-hover:brightness-75 transition-all duration-300 ease-in-out"
1918
[class.brightness-75]="currentSong?.url === getSongUrl(song)" />
@@ -27,7 +26,7 @@
2726
</div>
2827
</div>
2928

30-
<div class="flex-1">
29+
<div class="flex-1" (click)="playSong(getSongUrl(song), song)">
3130
<div class="flex items-center space-x-2 font-medium"
3231
[ngClass]="currentSong?.url === getSongUrl(song) ? 'text-[var(--theme-color)]' : 'text-[var(--color-text)]'">
3332
<img *ngIf="currentSong?.url === getSongUrl(song)" src="assets/img/music_icon/waves.gif"

src/app/features/music/music.component.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { ConfigService } from '../../service/config/config.service';
66
import { isPlatformBrowser } from '@angular/common';
77
import { FormModelComponent } from '../../component/form-model/form-model.component';
88
import { UserLikedSongsService } from '../../service/localStorage/user-liked-song.service';
9+
import { ViewChild, ElementRef } from '@angular/core';
10+
911
/**
1012
* Component to search, play, and suggest songs using Saavn API and AI suggestions.
1113
*
@@ -54,6 +56,9 @@ export class MusicComponent implements OnDestroy {
5456
/** Set to store URLs of liked songs */
5557
isCurrentSongLiked: boolean = false;
5658

59+
/** Reference to the search input element */
60+
@ViewChild('searchSongInput') searchSongInput!: ElementRef;
61+
5762
/**
5863
* Creates an instance of MusicComponent.
5964
*
@@ -76,6 +81,7 @@ export class MusicComponent implements OnDestroy {
7681
* Searches for songs based on the current query.
7782
*/
7883
searchSong(): void {
84+
this.removeFocus();
7985
const q = this.query.trim();
8086
if (q) {
8187
this.saavnService.searchSongs(q).subscribe((res) => {
@@ -317,4 +323,9 @@ export class MusicComponent implements OnDestroy {
317323
this.onSongFinished();
318324
}
319325

326+
/** Removes focus from the search input */
327+
removeFocus() {
328+
this.searchSongInput.nativeElement.blur();
329+
}
330+
320331
}

src/app/service/saavan-api/saavan.service.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ export class SaavnService {
3636
/**
3737
* Base URL for Saavn song search API.
3838
*/
39-
private baseUrl = 'https://saavn.dev/api/search/songs';
39+
private savvanApiUrl = 'https://saavn.dev/api/search/songs';
4040

4141
/**
4242
* Gemini API URL with authentication key from environment.
4343
*/
44-
private apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${environment.geminiApiKey}`;
44+
private geminiApiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${environment.geminiApiKey}`;
4545

4646
/**
4747
* Creates an instance of SaavnService.
@@ -52,7 +52,7 @@ export class SaavnService {
5252
constructor(
5353
private http: HttpClient,
5454
private globalLoaderService: GlobalLoaderService
55-
) {}
55+
) { }
5656

5757
/**
5858
* Searches for songs using the Saavn API.
@@ -63,7 +63,7 @@ export class SaavnService {
6363
searchSongs(query: string) {
6464
this.globalLoaderService.show("Searching songs...");
6565

66-
return this.http.get<any>(`${this.baseUrl}?query=${query}&limit=10&page=0`).pipe(
66+
return this.http.get<any>(`${this.savvanApiUrl}?query=${query}&limit=10&page=0`).pipe(
6767
finalize(() => {
6868
this.globalLoaderService.hide();
6969
})
@@ -133,7 +133,7 @@ Provide only the JSON object and no extra text, no formatting:
133133
const body = { contents: this.history };
134134

135135
try {
136-
const res: any = await firstValueFrom(this.http.post(this.apiUrl, body, { headers }));
136+
const res: any = await firstValueFrom(this.http.post(this.geminiApiUrl, body, { headers }));
137137
const parts = res?.candidates?.[0]?.content?.parts;
138138
const modelReply = parts?.map((p: any) => p.text).join('\n\n') || 'No response';
139139

0 commit comments

Comments
 (0)