aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Anshul Gupta <ansg191@yahoo.com> 2021-01-25 19:54:35 -0800
committerGravatar Anshul Gupta <ansg191@yahoo.com> 2021-01-25 19:54:35 -0800
commit481fcb1975047f5374a5c28abac65ae80e772126 (patch)
treea85fee020fe591aafcc0aa04ad90f8305b9ec2e1
parent4d7e4ca67681ae4f1b7555e0b90c9064f7e57b28 (diff)
downloadspotify-481fcb1975047f5374a5c28abac65ae80e772126.tar.gz
spotify-481fcb1975047f5374a5c28abac65ae80e772126.tar.zst
spotify-481fcb1975047f5374a5c28abac65ae80e772126.zip
Adds new search bar to playlists for future use
Adds search bar to the top of the playlists page for future use in using NLP to query songs in a playlist.
-rw-r--r--public/scripts/tracks.ts139
-rw-r--r--public/views/tracks.ejs18
2 files changed, 129 insertions, 28 deletions
diff --git a/public/scripts/tracks.ts b/public/scripts/tracks.ts
index 9930090..2ab6712 100644
--- a/public/scripts/tracks.ts
+++ b/public/scripts/tracks.ts
@@ -15,10 +15,10 @@ let totalSongs: number;
$(() => {
console.log(totalSongs);
- getSongs().then((total: number) => {
+ getSongs().then(() => {
console.log('Finished loading tracks');
// $('#search').attr("keyup", "search(this)");
- $('#search').on('keyup change', function () {
+ $('#searchByName').on('keyup change', function () {
const search: string = ($(this).val() as string).toLowerCase();
const trackElements = $('.container').children('.grid').children('div');
const tracks: { name: string, id: string }[] = [];
@@ -52,19 +52,23 @@ $(() => {
for (let i = 0; i < tracks.length; i++) {
let data = sessionStorage.getItem(tracks[i].id);
if (data != null) {
- changeInfo(tracks[i], JSON.parse(data));
+ changeInfo(tracks[i].id, JSON.parse(b64DecodeUnicode(data)));
}
}
}
$('#getGenre').prop('disabled', false);
});
+
+ let searchData = $('#search-data');
+ new TxtRotate($('#search'), searchData.data('rotate'), searchData.data('period'));
});
function getGenres() {
const progressBar = $("#progressBar");
const progressText = progressBar.children('div').eq(0);
const button = $('#getGenre');
+ const chunkSize = 48;
button.prop("disabled", true);
progressBar.parent().fadeIn();
@@ -76,16 +80,24 @@ function getGenres() {
function callback() {
if (queue.length > 0) {
- let track = queue.shift();
- progressBar.css('width', Math.round(100 - 100 * queue.length / length) + '%');
+ // let track = queue.shift();
progressText.text(`${(100 - 100 * queue.length / length).toFixed(1)}%`);
- getGenre(track, (timeout) => {
- if (!timeout) {
- setTimeout(callback, 0);
- } else {
- queue.push(track);
- setTimeout(callback, 2500);
- }
+ progressBar.css('width', Math.round(100 - 100 * queue.length / length) + '%');
+
+ let ids: string[] = [];
+ for (let i = 0; i < chunkSize; i++) {
+ let track = queue.shift();
+ if (track == null)
+ break;
+ ids.push(track.id);
+ }
+ getGenre(ids, () => {
+ // if (!timeout) {
+ callback();
+ // } else {
+ // queue.push(track);
+ // setTimeout(callback, 2500);
+ // }
});
} else {
console.timeEnd('Genres');
@@ -104,30 +116,37 @@ interface GenreResponse {
title: string
}
-function getGenre(track: SongType, callback: (timeout: boolean) => void) {
+function getGenre(id: string[], callback: () => void) {
$.ajax({
type: 'POST',
- url: "/genre",
+ url: "/genre/genres",
contentType: 'application/json',
- data: JSON.stringify(track),
- success: (data: GenreResponse) => {
- changeInfo(track, data);
-
- sessionStorage.setItem(track.id, JSON.stringify(data));
- return callback(false);
- },
- error: jqXHR => {
- if (jqXHR.status === 429) {
- return callback(true);
+ data: JSON.stringify(id),
+ success: (data: GenreResponse[]) => {
+ for (let i = 0; i < data.length; i++) {
+ if (data[i] == null)
+ continue;
+ changeInfo(id[i], data[i]);
+ // sessionStorage.setItem(id[i], JSON.stringify(data[i]));
+ sessionStorage.setItem(id[i], b64EncodeUnicode(JSON.stringify(data[i])));
}
+ // changeInfo(id, data);
- return callback(false);
+ // sessionStorage.setItem(id.id, JSON.stringify(data));
+ return callback();
}
+ // error: jqXHR => {
+ // if (jqXHR.status === 429) {
+ // return callback(true);
+ // }
+ //
+ // return callback(false);
+ // }
});
}
-function changeInfo(track: SongType, data: GenreResponse) {
- const id = track.id;
+function changeInfo(id: string, data: GenreResponse) {
+ // const id = id.id;
const container = $(`#${id}_info`);
const results = container.children('div');
const texts = container.children('h4');
@@ -221,4 +240,70 @@ function createTile(grid: JQuery, track: SongType) {
</div>
</div>`
)
+}
+
+function b64EncodeUnicode(str: string) {
+ return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (match: string, p1: string) => {
+ return String.fromCharCode(parseInt(p1, 16));
+ })
+ );
+}
+
+function b64DecodeUnicode(str: string) {
+ return decodeURIComponent(atob(str).split('').map((c: string) => {
+ return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
+ }).join(''));
+}
+
+class TxtRotate {
+ private readonly toRotate: string[];
+ private el: JQuery<HTMLInputElement>;
+ private loopNum: number;
+ private readonly period: number;
+ private txt: string;
+ private isDeleting: boolean;
+
+ constructor(el: JQuery<HTMLInputElement>, toRotate: string[], period: number) {
+ this.toRotate = toRotate;
+ this.el = el;
+ this.loopNum = 0;
+ this.period = period;
+ this.txt = '';
+ this.isDeleting = false
+ this.tick();
+ }
+
+ private tick() {
+ let i = this.loopNum % this.toRotate.length;
+ // let i = Math.floor(Math.random() * this.toRotate.length);
+ // console.log(i);
+ let fullTxt = this.toRotate[i];
+
+ if (this.isDeleting) {
+ this.txt = fullTxt.substring(0, this.txt.length - 1);
+ } else {
+ this.txt = fullTxt.substring(0, this.txt.length + 1);
+ }
+
+ // this.el.html(`<span class="wrap">${this.txt}</span>`);
+ this.el.attr('placeholder', this.txt);
+
+ let delta = 200 - Math.random() * 100;
+
+ if (this.isDeleting)
+ delta /= 2;
+
+ if (!this.isDeleting && this.txt === fullTxt) {
+ delta = this.period;
+ this.isDeleting = true;
+ } else if (this.isDeleting && this.txt === '') {
+ this.isDeleting = false;
+ this.loopNum++;
+ delta = 500;
+ }
+
+ setTimeout(() => {
+ this.tick();
+ }, delta);
+ }
} \ No newline at end of file
diff --git a/public/views/tracks.ejs b/public/views/tracks.ejs
index b2d1f58..30e6576 100644
--- a/public/views/tracks.ejs
+++ b/public/views/tracks.ejs
@@ -18,6 +18,22 @@
<body>
<div>
<h1 class="text-center text-6xl font-bold mb-10"><%- playlist.name %></h1>
+ <div class="bg-gray-50">
+ <div class="p-8 container m-auto">
+ <div class="bg-white flex items-center rounded-full shadow-xl">
+ <input class="rounded-l-full w-full py-4 px-6 text-gray-700 leading-tight focus:outline-none text-2xl"
+ id="search" type="text" placeholder="Search">
+
+ <div id="search-data" data-period="2000" data-rotate='["Hello World!", "World Hello!", "This is a test", "WOW!!!"]'></div>
+
+ <div class="p-4">
+ <button class="bg-blue-500 text-white rounded-full p-2 hover:bg-blue-400 focus:outline-none w-12 h-12 flex items-center justify-center">
+ <i class="fas fa-search"></i>
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
<div class="flex flex-row m-auto justify-center">
<div class="w-64 mr-20">
<div class="bg-gray-300 shadow-lg rounded py-5">
@@ -32,7 +48,7 @@
class="bg-white shadow rounded border-0 p-3"
placeholder="Search by name..."
style="width: 200px"
- id="search">
+ id="searchByName">
</div>
</div>
</div>