Skip to content

Commit d073cbc

Browse files
committed
Add playlist selection, fixes and tweaks
1 parent e503162 commit d073cbc

14 files changed

Lines changed: 529 additions & 119 deletions

.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
REACT_APP_API_BASE_URL = "http://apollo:3678"
2-
REACT_APP_WS_URL = "ws://apollo:3678/events"
1+
REACT_APP_API_BASE_URL = "http://localhost:3678"
2+
REACT_APP_WS_URL = "ws://localhost:3678/events"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@stronk-tech/react-librespot-controller",
33
"description": "`go-librespot` squeezebox-alike web frontend for small touchscreens",
4-
"version": "0.0.27",
4+
"version": "0.1.0",
55
"main": "dist/index.cjs.js",
66
"module": "dist/index.esm.js",
77
"files": [

src/components/Album/AlbumCard.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
height: auto;
138138
object-fit: cover;
139139
display: block;
140+
aspect-ratio: 1/1;
140141
border-radius: inherit;
141142
box-sizing: border-box;
142143
position: relative;

src/components/Album/AlbumCard.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ const AlbumCard = ({ title, subtitle, image, isStopped }) => {
9797
>
9898
<canvas ref={canvasRef} style={{ display: 'none' }}></canvas>
9999
{
100-
isStopped ? (<div className="spotify-player-album-card-image"><PlaceholderAlbum /></div>) : (
100+
isStopped && !image ? (<div className="spotify-player-album-card-image"><PlaceholderAlbum /></div>) : (
101101
<div className="spotify-player-album-card-container">
102102
<div className="spotify-player-album-card-container-border"></div>
103103
<div className="spotify-player-album-card-image-container">
@@ -107,9 +107,9 @@ const AlbumCard = ({ title, subtitle, image, isStopped }) => {
107107
src={image}
108108
/>
109109
</div>
110-
{/* <div className="spotify-player-album-card-title-container">
110+
{title && <div className="spotify-player-album-card-title-container">
111111
<div className="spotify-player-album-card-title">{title}</div>
112-
</div> */}
112+
</div>}
113113
<div className="spotify-player-album-card-subtitle">{subtitle}</div>
114114
</div>
115115
)

src/components/Album/PlaceHolderAlbum.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
/* Placeholder.css */
22
.spotify-player-placeholder-album {
3-
height: 120px;
43
border-radius: 8px;
54
background: var(--darker);
65
display: flex;
6+
aspect-ratio: 1/1;
7+
width: 100%;
78
align-items: center;
89
justify-content: center;
910
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);

src/components/Info/Header.css

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,69 @@
11
/* Title + Icon container */
2+
.spotify-player-header {
3+
display: flex;
4+
flex-direction: row;
5+
align-items: center;
6+
gap: 0.8em;
7+
width: 100%;
8+
}
9+
10+
/* Tabs */
11+
.spotify-player-tabs {
12+
display: flex;
13+
gap: 1em;
14+
justify-content: center;
15+
}
16+
17+
.spotify-player-tab {
18+
background-color: var(--button-background);
19+
color: var(--button-text-color);
20+
border: 1px solid var(--button-border);
21+
border-radius: 0.3em;
22+
padding: 0.4em 1em;
23+
font-size: 1rem;
24+
display: flex;
25+
align-items: center;
26+
gap: 0.5em;
27+
transition: all 0.2s ease-in-out;
28+
cursor: pointer;
29+
}
30+
31+
.spotify-player-tab:hover {
32+
background-color: var(--accent-color);
33+
color: var(--darkest);
34+
}
35+
36+
.spotify-player-tab:disabled {
37+
background-color: var(--button-border);
38+
color: var(--description-color);
39+
cursor: not-allowed;
40+
}
41+
42+
.spotify-player-tab-active {
43+
background-color: var(--button-hover-background);
44+
color: var(--accent-color);
45+
font-weight: bold;
46+
}
247

348
.spotify-player-device-title {
449
display: flex;
5-
flex-direction: row;
50+
align-items: center;
651
gap: 1em;
752
text-align: center;
853
background-color: var(--dark);
954
width: 100%;
10-
transition: width 0.3s ease, height 0.3s ease, filter 0.3s ease, z-index 0s;
1155
justify-content: center;
1256
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
13-
align-items: center;
1457
padding: 0.4em;
15-
padding-left: 0.3em;
16-
padding-right: 0.3em;
1758
border-radius: 0.2em;
18-
margin: 0;
19-
margin-bottom: 0.5em;
2059
}
2160

2261
/* Title device name styling */
2362

2463
.spotify-player-device-title h4 {
2564
font-weight: bold;
26-
text-align: center;
2765
font-size: 1.5rem;
2866
color: var(--weird);
29-
text-align: center;
3067
margin: 0;
3168
transition: transform 0.2s, color 0.3s ease;
3269
}
@@ -58,4 +95,4 @@
5895
100% {
5996
transform: rotate(360deg);
6097
}
61-
}
98+
}

src/components/Info/Header.js

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,17 @@ import {
1010
GiRadioTower,
1111
GiNightSleep,
1212
} from "react-icons/gi";
13-
import { FaTabletAlt, FaCar, FaMusic, FaQuestionCircle, FaChromecast, FaExclamationCircle } from "react-icons/fa";
13+
import {
14+
FaTabletAlt,
15+
FaCar,
16+
FaMusic,
17+
FaQuestionCircle,
18+
FaChromecast,
19+
FaExclamationCircle,
20+
FaInfoCircle,
21+
} from "react-icons/fa";
1422
import { MdWatch } from "react-icons/md";
15-
import './Header.css';
23+
import "./Header.css";
1624

1725
// Mapping from device type to which Icon we should render
1826
const deviceIcons = {
@@ -38,16 +46,52 @@ const deviceIcons = {
3846
// TODO: expand with settings button
3947
// TODO: expand with playlists/albums/explore button once we can get albums/playlists from the API
4048
// TODO: add more comments, IE for props
41-
const Header = ({ isConnected, deviceName, isPlaying, deviceType, isStopped }) => {
42-
const Icon = isStopped ? GiNightSleep : deviceIcons[deviceType?.toLowerCase()] || FaQuestionCircle;
49+
const Header = ({
50+
isConnected,
51+
deviceName,
52+
isPlaying,
53+
deviceType,
54+
isStopped,
55+
activeTab,
56+
setActiveTab,
57+
}) => {
58+
const Icon = isStopped
59+
? GiNightSleep
60+
: deviceIcons[deviceType?.toLowerCase()] || FaQuestionCircle;
61+
4362
return (
44-
<div className="spotify-player-device-title">
45-
{isConnected ? (
46-
<Icon className={isPlaying ? "spotify-player-connected-icon spotify-player-rotating" : "spotify-player-connected-icon"} />
47-
) : (
48-
<FaExclamationCircle className="spotify-player-connected-icon spotify-player-disconnected" />
49-
)}
50-
<h4>{isConnected ? deviceName : "Disconnected"}</h4>
63+
<div className="spotify-player-header">
64+
<div className="spotify-player-device-title">
65+
{isConnected ? (
66+
<Icon
67+
className={
68+
isPlaying
69+
? "spotify-player-connected-icon spotify-player-rotating"
70+
: "spotify-player-connected-icon"
71+
}
72+
/>
73+
) : (
74+
<FaExclamationCircle className="spotify-player-connected-icon spotify-player-disconnected" />
75+
)}
76+
<h4>{isConnected ? deviceName : "Disconnected"}</h4>
77+
</div>
78+
<div className="spotify-player-tabs">
79+
<button
80+
className={`spotify-player-tab ${activeTab === "Info" ? "spotify-player-tab-active" : ""
81+
}`}
82+
onClick={() => setActiveTab("Info")}
83+
>
84+
<FaInfoCircle />
85+
</button>
86+
<button
87+
className={`spotify-player-tab ${activeTab === "Playlists" ? "spotify-player-tab-active" : ""
88+
}`}
89+
onClick={() => setActiveTab("Playlists")}
90+
disabled={!isConnected}
91+
>
92+
<FaMusic />
93+
</button>
94+
</div>
5195
</div>
5296
);
5397
};

src/components/Info/Playlists.css

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
.spotify-player-playlists-wrapper {
2+
overflow: hidden;
3+
flex: 1;
4+
box-sizing: border-box;
5+
overflow-x: auto;
6+
background-color: var(--darkest);
7+
border: 1px solid var(--grey);
8+
padding: 1.2em;
9+
border-radius: 0.5em;
10+
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);
11+
position: relative;
12+
}
13+
14+
.spotify-player-playlist-container {
15+
display: grid;
16+
gap: 1em;
17+
}
18+
19+
.spotify-player-playlist-container::-webkit-scrollbar {
20+
width: 10px;
21+
}
22+
23+
.spotify-player-playlist-container::-webkit-scrollbar-thumb {
24+
background: var(--scrollbar-thumb-color);
25+
border-radius: 10px;
26+
}
27+
28+
.spotify-player-playlist-container::-webkit-scrollbar-thumb:hover {
29+
background: var(--scrollbar-thumb-hover-color);
30+
}
31+
32+
.spotify-player-arrow {
33+
position: absolute;
34+
right: 1em;
35+
top: 50%;
36+
transform: translateY(-50%);
37+
font-size: 2rem;
38+
color: var(--subtext-color);
39+
pointer-events: none;
40+
opacity: 0.7;
41+
transition: opacity 0.2s ease-in-out, transform 0.0s ease;
42+
}
43+
44+
.spotify-player-arrow.arrow-visible {
45+
opacity: 0.7;
46+
}
47+
48+
.spotify-player-arrow:hover {
49+
opacity: 1;
50+
}
51+
52+
.spotify-player-arrow.arrow-hidden {
53+
opacity: 0;
54+
}
55+
56+
.spotify-player-playlist-item {
57+
display: flex;
58+
flex-direction: row;
59+
align-items: center;
60+
justify-content: space-around;
61+
gap: 0.5em;
62+
padding: 0.5em;
63+
background-color: var(--dark);
64+
border: 1px solid var(--button-border);
65+
border-radius: 0.5em;
66+
cursor: pointer;
67+
scroll-snap-align: start;
68+
transition: transform 0.2s ease-in-out, background-color 0.2s ease-in-out;
69+
overflow: hidden;
70+
width: 200px;
71+
}
72+
73+
.spotify-player-playlist-item:hover {
74+
transform: scale(1.05);
75+
background-color: var(--grey);
76+
}
77+
78+
.spotify-player-playlist-item.active {
79+
background-color: var(--accent-color);
80+
}
81+
82+
.spotify-player-playlist-item.active .spotify-player-playlist-info h4 {
83+
color: var(--darkest);
84+
}
85+
86+
.spotify-player-playlist-item.active .spotify-player-playlist-info p {
87+
color: var(--dark);
88+
font-weight: bold;
89+
}
90+
91+
.spotify-player-playlist-image {
92+
width: 50px;
93+
height: 50px;
94+
border-radius: 0.5em;
95+
}
96+
97+
.spotify-player-playlist-info {
98+
text-align: start;
99+
white-space: nowrap;
100+
overflow: hidden;
101+
text-overflow: ellipsis;
102+
flex: 1;
103+
}
104+
105+
.spotify-player-playlist-info h4 {
106+
margin: 0;
107+
white-space: nowrap;
108+
overflow: hidden;
109+
font-size: 1rem;
110+
text-overflow: ellipsis;
111+
}
112+
113+
.spotify-player-playlist-info p {
114+
margin: 0;
115+
white-space: nowrap;
116+
overflow: hidden;
117+
font-size: 0.875rem;
118+
text-overflow: ellipsis;
119+
}
120+
121+
.spotify-player-play-button {
122+
color: var(--blue);
123+
background-color: var(--dark);
124+
border: 1px solid var(--darker);
125+
border-radius: 0.5em;
126+
cursor: pointer;
127+
padding: 0.5em 0.75em;
128+
font-size: 1rem;
129+
cursor: pointer;
130+
transition: background-color 0.2s ease-in-out transform 0.2s ease-in-out;
131+
}
132+
133+
.spotify-player-play-button:hover {
134+
background-color: var(--button-hover-background);
135+
color: var(--magenta);
136+
transform: scale(1.05);
137+
}

0 commit comments

Comments
 (0)