Skip to content

Commit 6c211a4

Browse files
committedMar 17, 2021
add lyrics search app
1 parent f166b31 commit 6c211a4

File tree

6 files changed

+269
-3
lines changed

6 files changed

+269
-3
lines changed
 

‎70-typing game/style.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ button:focus, input:focus {
6464
.settings-btn {
6565
position: absolute;
6666
bottom: 30px;
67-
left: 30px;
67+
right: 30px;
6868
}
6969

7070
.settings {

‎73-lyrics search app/index.html

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<link rel="stylesheet" href="style.css" />
7+
<title>Lyrics Search</title>
8+
</head>
9+
<body>
10+
<header>
11+
<h1>Lyrics Search</h1>
12+
<form id="form">
13+
<input
14+
type="text"
15+
id="search"
16+
placeholder="Enter artist or song name..."
17+
/>
18+
<button>Search</button>
19+
</form>
20+
</header>
21+
<div id="result" class="container">
22+
<p>Results will be displayed here</p>
23+
</div>
24+
<div id="more" class="container centered"></div>
25+
<script src="script.js"></script>
26+
</body>
27+
</html>

‎73-lyrics search app/script.js

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
const form = document.getElementById("form");
2+
const search = document.getElementById("search");
3+
const result = document.getElementById("result");
4+
// const more = document.getElementById("more");
5+
6+
const apiURL = "https://api.lyrics.ovh";
7+
8+
async function searchSongs(term) {
9+
const res = await fetch(`${apiURL}/suggest/${term}`);
10+
const data = await res.json();
11+
showData(data);
12+
}
13+
14+
async function getLyrics(artist, songTitle) {
15+
const res = await fetch(`${apiURL}/v1/${artist}/${songTitle}`);
16+
const data = await res.json();
17+
console.log(artist, songTitle);
18+
if (data.error) {
19+
showAlert(data.error);
20+
} else {
21+
const lyrics = data.lyrics.replace(/(\r\n|\r|\n)/g, "<br>");
22+
23+
result.innerHTML = `
24+
<h2><strong>${artist}</strong> - ${songTitle}</h2>
25+
<span>${lyrics}</span>
26+
`;
27+
}
28+
// more.innerHTML = "";
29+
}
30+
31+
// async function getMoreSongs(url) {
32+
// const res = await fetch(`https://cors-anywhere.herokuapp.com/${url}`); // 403 without
33+
// const data = await res.json();
34+
// showData(data);
35+
// }
36+
37+
function showData(data) {
38+
result.innerHTML = `
39+
<ul class="songs">
40+
${data.data
41+
.map(
42+
(song) => `<li>
43+
<span><strong>${song.artist.name}</strong> - ${song.title}</span>
44+
<button class="btn" data-artist="${song.artist.name}" data-songtitle="${song.title}">Get Lyrics</button>
45+
</li>`
46+
)
47+
.join("")}
48+
</ul>
49+
`;
50+
// Pagination
51+
// if (data.prev || data.next) {
52+
// more.innerHTML = `
53+
// ${
54+
// data.prev
55+
// ? `<button class="btn" onclick="getMoreSongs('${data.prev}')">Prev</button>`
56+
// : ""
57+
// }
58+
// ${
59+
// data.next
60+
// ? `<button class="btn" onclick="getMoreSongs('${data.next}')">Next</button>`
61+
// : ""
62+
// }
63+
// `;
64+
// } else more.innerHTML = "";
65+
}
66+
67+
function showAlert(message) {
68+
const notif = document.createElement("div");
69+
notif.classList.add("toast");
70+
notif.innerText = message;
71+
document.body.appendChild(notif);
72+
setTimeout(() => notif.remove(), 3000);
73+
}
74+
75+
// Event Listeners
76+
form.addEventListener("submit", (e) => {
77+
e.preventDefault();
78+
const searchTerm = search.value.trim();
79+
if (!searchTerm) showAlert("Please type in a search term");
80+
else searchSongs(searchTerm);
81+
});
82+
result.addEventListener("click", (e) => {
83+
const clickedElement = e.target;
84+
if (clickedElement.tagName === "BUTTON") {
85+
const artist = clickedElement.getAttribute("data-artist");
86+
const songTitle = clickedElement.getAttribute("data-songtitle");
87+
getLyrics(artist, songTitle);
88+
}
89+
});
90+
91+
// Init
92+
searchSongs("one");

‎73-lyrics search app/style.css

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
@import url('https://fonts.googleapis.com/css2?family=Rubik:wght@400;700&display=swap');
2+
3+
:root {
4+
--main-color: #3B9B76;
5+
--secondary-color: #5AB193;
6+
--text-color: rgba(255,255,255,0.87);
7+
}
8+
9+
* {
10+
box-sizing: border-box;
11+
}
12+
13+
body {
14+
font-family: "Rubik", sans-serif;
15+
margin: 0;
16+
}
17+
18+
header {
19+
background: url('https://images.unsplash.com/photo-1495305379050-64540d6ee95d?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80') no-repeat center center/cover;
20+
color: rgba(255,255,255,0.95);
21+
display: flex;
22+
flex-direction: column;
23+
align-items: center;
24+
justify-content: center;
25+
padding: 6.25rem 0;
26+
position: relative;
27+
}
28+
29+
header::after {
30+
content: '';
31+
position: absolute;
32+
top: 0;
33+
left: 0;
34+
width: 100%;
35+
height: 100%;
36+
background-color: rgba(0,0,0,0.8);
37+
}
38+
39+
header * {
40+
z-index: 1;
41+
}
42+
43+
header h1 {
44+
margin: 0 0 2rem;
45+
}
46+
47+
form {
48+
position: relative;
49+
width: 31.25rem;
50+
max-width: 90%;
51+
}
52+
53+
form input {
54+
border: 0;
55+
border-radius: 50px;
56+
font-size: 1rem;
57+
padding: 1rem 2rem;
58+
width: 100%;
59+
}
60+
61+
form button {
62+
background-color: var(--main-color);
63+
color: rgba(255,255,255,0.95);
64+
position: absolute;
65+
top: 0.125rem;
66+
right: 0.125rem;
67+
border: 0;
68+
border-radius: 50px;
69+
font-size: 1rem;
70+
padding: 0.875rem 2rem;
71+
}
72+
73+
form button:hover {
74+
background-color: var(--secondary-color);
75+
}
76+
77+
button {
78+
cursor: pointer;
79+
}
80+
81+
button:active {
82+
transform: scale(0.95);
83+
}
84+
85+
input:focus, button:focus {
86+
outline: none;
87+
}
88+
89+
.btn {
90+
background-color: var(--secondary-color);
91+
border: 0;
92+
border-radius: 10px;
93+
color: #fff;
94+
padding: 0.25rem 0.625rem;
95+
}
96+
97+
.btn:hover {
98+
background-color: var(--main-color);
99+
}
100+
101+
ul.songs {
102+
list-style-type: none;
103+
padding: 0;
104+
}
105+
106+
ul.songs li {
107+
display: flex;
108+
align-items: center;
109+
justify-content: space-between;
110+
margin: 0.625rem 0;
111+
}
112+
113+
.container {
114+
margin: 2rem auto;
115+
width: 31.25rem;
116+
max-width: 90%;
117+
}
118+
119+
.container h2 {
120+
font-weight: 300;
121+
}
122+
123+
.container p {
124+
text-align: center;
125+
}
126+
127+
.centered {
128+
display: flex;
129+
justify-content: center;
130+
}
131+
132+
.centered button {
133+
transform: scale(1.3);
134+
margin: 15px;
135+
}
136+
137+
.toast {
138+
position: fixed;
139+
bottom: 10px;
140+
right: 10px;
141+
background-color: var(--secondary-color);
142+
color: var(--text-color);
143+
border-radius: 50px;
144+
font-size: 1rem;
145+
padding: 0.875rem 2rem;
146+
margin: 0.5rem;
147+
}

‎78-speak number guessing game/script.js

Whitespace-only changes.

‎README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@
7878
| 70 | [Typing Game](https://github.com/solygambas/html-css-fifty-projects/tree/master/70-typing%20game) | [Live Demo](https://codepen.io/solygambas/full/wvoOQvq) |
7979
| 71 | [Speech Text Reader](https://github.com/solygambas/html-css-fifty-projects/tree/master/71-speech%20text%20reader) | [Live Demo](https://codepen.io/solygambas/full/QWGPLVM) |
8080
| 72 | [Memory Cards](https://github.com/solygambas/html-css-fifty-projects/tree/master/72-memory%20cards) | [Live Demo](https://codepen.io/solygambas/full/oNYOqjv) |
81-
| 73 | [Lyrics Search App](https://github.com/solygambas/html-css-fifty-projects/tree/master/73-lyrics%20search%20app) | [Live Demo](#) |
82-
| 74 | [Relaxer App](https://github.com/solygambas/html-css-fifty-projects/tree/master/74-relaxer%20app) | [Live Demo](#) |
81+
| 73 | [Lyrics Search App](https://github.com/solygambas/html-css-fifty-projects/tree/master/73-lyrics%20search%20app) | [Live Demo](https://codepen.io/solygambas/full/ExNzPKV) |
82+
| 74 | [Relaxer App](https://github.com/solygambas/html-css-fifty-projects/tree/master/74-relaxer%20app) | [Live Demo](https://codepen.io/solygambas/full/wvobMzE) |
8383
| 75 | [Breakout Game](https://github.com/solygambas/html-css-fifty-projects/tree/master/75-breakout%20game) | [Live Demo](#) |
8484
| 76 | [New Year Countdown](https://github.com/solygambas/html-css-fifty-projects/tree/master/76-new%20year%20countdown) | [Live Demo](#) |
8585
| 77 | [Sortable List](https://github.com/solygambas/html-css-fifty-projects/tree/master/77-sortable%20list) | [Live Demo](#) |

0 commit comments

Comments
 (0)
Please sign in to comment.