-
Notifications
You must be signed in to change notification settings - Fork 186
Expand file tree
/
Copy pathDashboard.js
More file actions
116 lines (105 loc) · 3.14 KB
/
Dashboard.js
File metadata and controls
116 lines (105 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import { useState, useEffect } from "react"
import useAuth from "./useAuth"
import Player from "./Player"
import LightModeIcon from "@material-ui/icons/Brightness5"
import DarkModeIcon from "@material-ui/icons/Brightness4"
import TrackSearchResult from "./TrackSearchResult"
import { Container, Form } from "react-bootstrap"
import SpotifyWebApi from "spotify-web-api-node"
import axios from "axios"
const spotifyApi = new SpotifyWebApi({
clientId: "8b945ef10ea24755b83ac50cede405a0",
})
export default function Dashboard({ code, toggleTheme, theme }) {
const accessToken = useAuth(code)
const [search, setSearch] = useState("")
const [searchResults, setSearchResults] = useState([])
const [playingTrack, setPlayingTrack] = useState()
const [lyrics, setLyrics] = useState("")
function chooseTrack(track) {
setPlayingTrack(track)
setSearch("")
setLyrics("")
}
useEffect(() => {
if (!playingTrack) return
axios
.get("http://localhost:3001/lyrics", {
params: {
track: playingTrack.title,
artist: playingTrack.artist,
},
})
.then(res => {
setLyrics(res.data.lyrics)
})
}, [playingTrack])
useEffect(() => {
if (!accessToken) return
spotifyApi.setAccessToken(accessToken)
}, [accessToken])
useEffect(() => {
if (!search) return setSearchResults([])
if (!accessToken) return
let cancel = false
spotifyApi.searchTracks(search).then(res => {
if (cancel) return
setSearchResults(
res.body.tracks.items.map(track => {
const smallestAlbumImage = track.album.images.reduce(
(smallest, image) => {
if (image.height < smallest.height) return image
return smallest
},
track.album.images[0]
)
return {
artist: track.artists[0].name,
title: track.name,
uri: track.uri,
albumUrl: smallestAlbumImage.url,
}
})
)
})
return () => (cancel = true)
}, [search, accessToken])
return (
<Container className="d-flex flex-column py-2" style={{ height: "100vh" }}>
<button
className="btn"
style={{ marginLeft: "auto", marginBottom: "2rem", background: theme.btnBackground }}
onClick={toggleTheme}
>
{theme.name === "dark" ? <LightModeIcon /> : <DarkModeIcon />}
</button>
<Form.Control
type="search"
placeholder="Search Songs/Artists"
value={search}
onChange={e => setSearch(e.target.value)}
/>
<div className="flex-grow-1 my-2" style={{ overflowY: "auto" }}>
{searchResults.map(track => (
<TrackSearchResult
track={track}
key={track.uri}
chooseTrack={chooseTrack}
/>
))}
{searchResults.length === 0 && (
<div className="text-center" style={{ whiteSpace: "pre" }}>
{lyrics}
</div>
)}
</div>
<div>
<Player
accessToken={accessToken}
trackUri={playingTrack?.uri}
theme={theme}
/>
</div>
</Container>
)
}