Compare commits

..

6 Commits

Author SHA1 Message Date
Brandon4466
6ba4ac0ea6 added left side pane with transition, content to be added 2024-05-13 17:01:57 -07:00
cfdf406f6c background fades to new color, new left side menu (WIP) 2024-05-12 21:18:59 -07:00
7adb79881e Revert "revert 49cd2b87355a0031b1376f1842d894c19f0f0d67"
This reverts commit d3a4e97180.

redoing previous revert
2024-05-08 14:57:45 -07:00
b0f8467a5e added file to .gitignore 2024-05-08 14:44:39 -07:00
7eff3f8d78 add 2024-05-08 14:16:52 -07:00
d3a4e97180 revert 49cd2b8735
undoing accidental merge
2024-05-08 14:15:06 -07:00
7 changed files with 97 additions and 69 deletions

3
.gitignore vendored
View File

@@ -3,3 +3,6 @@ client_secret
code code
spotify-gui.js.code-workspace spotify-gui.js.code-workspace
.syncedlyrics/musixmatch_token.json .syncedlyrics/musixmatch_token.json
__pycache__/_canvas.cpython-310.pyc
protos/__pycache__/canvas_pb2.cpython-310.pyc
__pycache__/_canvas.cpython-310.pyc

View File

@@ -1 +1 @@
{"token": "240507dc1c1d721b422f329d191594415da1e4aec72fa0405c547e", "expiration_time": 1715112558} {"token": "2405132d7b80d1a072129196642e3c2675e8f036f7663fa58037a0", "expiration_time": 1715576057}

Binary file not shown.

View File

@@ -4,7 +4,6 @@ from urllib.parse import urlencode
import base64 import base64
import os import os
import _canvas as SpotifyCanvas import _canvas as SpotifyCanvas
import time
import syncedlyrics import syncedlyrics
dev = 0 dev = 0
@@ -92,7 +91,6 @@ def callback():
@app.route('/appdata') @app.route('/appdata')
def appdata(): def appdata():
global access_token global access_token
stime = time.time()
try: try:
user_headers = { user_headers = {
"Authorization": "Bearer " + access_token, "Authorization": "Bearer " + access_token,
@@ -103,14 +101,13 @@ def appdata():
currently_playing = requests.get("https://api.spotify.com/v1/me/player/currently-playing", headers=user_headers) currently_playing = requests.get("https://api.spotify.com/v1/me/player/currently-playing", headers=user_headers)
# needs to add an if statement that says if song is not playing then, becuase when nothing is playing the json response is different.
if currently_playing.content: if currently_playing.content:
if "is_playing" in currently_playing.json(): if "is_playing" in currently_playing.json():
if currently_playing.json()["is_playing"] is True and currently_playing.json()["item"]["id"] == request.args.get('id'): if currently_playing.json()["is_playing"] is True and currently_playing.json()["item"]["id"] == request.args.get('id'):
print("QUICK" + str(time.time() - stime))
return { 'progress_ms': currently_playing.json()["progress_ms"], return { 'progress_ms': currently_playing.json()["progress_ms"],
} }
elif currently_playing.json()["is_playing"] is True and currently_playing.json()["item"]["id"] != request.args.get('id'): elif currently_playing.json()["is_playing"] is True and currently_playing.json()["item"]["id"] != request.args.get('id'):
print("FULL" + str(time.time() - stime))
return { 'id': currently_playing.json()["item"]["id"], return { 'id': currently_playing.json()["item"]["id"],
'name': currently_playing.json()["item"]["name"], 'name': currently_playing.json()["item"]["name"],
'artist': currently_playing.json()["item"]["artists"][0]["name"], 'artist': currently_playing.json()["item"]["artists"][0]["name"],
@@ -170,7 +167,6 @@ def icons(filename):
@app.route('/canvas') @app.route('/canvas')
def canvas(): def canvas():
print("CANVAS")
id = request.args.get('id') id = request.args.get('id')
try: try:
return { 'canvas_url': SpotifyCanvas.get_canvas_for_track(SpotifyCanvas.get_access_token(), id) } return { 'canvas_url': SpotifyCanvas.get_canvas_for_track(SpotifyCanvas.get_access_token(), id) }
@@ -183,10 +179,10 @@ def lyrics():
artist = request.args.get('artist') artist = request.args.get('artist')
if name and artist is not None: if name and artist is not None:
full_lyrics = syncedlyrics.search("[" + name + "] [" + artist + "]") full_lyrics = syncedlyrics.search("[" + name + "] [" + artist + "]")
if full_lyrics is None:
return { 'lyrics': "no lyrics" }
else: else:
return { 'lyrics': '' } return { 'lyrics': '' }
if full_lyrics is None:
return { 'lyrics': "no lyrics" }
return { 'lyrics': full_lyrics } return { 'lyrics': full_lyrics }
if __name__ == '__main__': if __name__ == '__main__':

View File

@@ -8,27 +8,19 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/color-thief/2.3.0/color-thief.umd.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/color-thief/2.3.0/color-thief.umd.js"></script>
<style> <style>
.animated-background { .animated-background {
transition: background-color 1s ease-in-out; /* add a transition effect */ transition: background-color 1s ease-in-out, margin-left 0.5s; /* add a transition effect */
background-color: #fff; /* initial background color */ background-color: var(--color); /* initial background color */
}
.animated-background.update-color {
background-color: var(--color); /* change the background color to black */
}
@keyframes fade-in {
to {
background-color: var(--color); /* change the background color to black */
}
} }
.progress-container { .progress-container {
position: fixed; position: fixed;
bottom: 8px; bottom: 8px;
width: 100%; width: 100%;
background-color: #ddd; transition: background-color 1s ease-in-out; /* add a transition effect */
background-color: var(--color);
} }
.progress-bar { .progress-bar {
width: 0%; width: 0%;
height: 10px; height: 10px;
background-color: #d734e9;
text-align: center; text-align: center;
line-height: 4px; line-height: 4px;
color: white; color: white;
@@ -39,12 +31,14 @@
font-weight: bold; font-weight: bold;
text-align: center; text-align: center;
margin-bottom: 5px; margin-bottom: 5px;
transition: color 1s ease-in-out; /* add a transition effect */
} }
.artist-text { .artist-text {
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
font-size: 29px; font-size: 29px;
text-align: center; text-align: center;
margin-top: 5px; margin-top: 5px;
transition: color 1s ease-in-out; /* add a transition effect */
} }
.middle { .middle {
position: relative; position: relative;
@@ -69,6 +63,7 @@
text-align: center; text-align: center;
} }
.buttons { .buttons {
transition: filter 1s ease-in-out; /* add a transition effect */
position: absolute; position: absolute;
bottom: 0; bottom: 0;
left: 0; left: 0;
@@ -91,39 +86,60 @@
vertical-align: center; vertical-align: center;
width: 33%; width: 33%;
} }
/* LEFT SIDE SWIPE PAGE */
.leftside {
height: 100%;
width: 0;
position: fixed;
top: 0;
left: 0;
background-color: var(--color);
overflow-x: hidden;
transition: 0.5s;
}
</style> </style>
</head> </head>
<body class="animated-background"> <body class="animated-background">
<!-- <link href="http://127.0.0.1:8888/font" rel="stylesheet"> --> <!-- <link href="http://127.0.0.1:8888/font" rel="stylesheet"> -->
<div class="total"> <div class="total">
<div class="left"> <div class="leftside" id="leftpage">
<img id="image" src="{{ data['image'] }}" alt="Song Image" type="image/jpeg" style="max-width: 330px; padding-left: 25%;"> <a href="javascript:void(0)" onclick="closeNav()">Close</a>
<video width="330" autoplay muted playsinline loop id="canvas_url" src="{{ data['canvas_url'] }}" type="video/mp4" style="display: none; padding-left: 10%;"></video> <div class="total">
</div> <div class="left">
<div class="middle">
<p id="name" class="song-text">{{ data['name'] }}</p> </div>
<p id="artist" class="artist-text">{{ data['artist'] }}</p> <div class="middle">
<!-- <p id="album" class="song-info">{{ data['album'] }}</p> <input type="range" id="volume">
<p id="progress_ms">{{ data['progress_ms'] }}</p> </div>
<p id="duration_ms">{{ data['duration_ms'] }}</p> --> <div class="right">
<p>
<div class="buttons"> </div>
<a><img id="previous" src="http://127.0.0.1:8888/icons/previous.png" class="buttons-individual"></a> </div>
<a><img id="playpause" src="http://127.0.0.1:8888/icons/play.png" class="buttons-individual"></a> </div>
<a><img id="next" src="http://127.0.0.1:8888/icons/next.png" class="buttons-individual"></a> <span onclick="openNav()">Swipe</span>
<a><img id="like" src="http://127.0.0.1:8888/icons/heart.png" class="buttons-individual" style="display:none;"></a> <div class="left">
<img id="image" src="{{ data['image'] }}" alt="Song Image" type="image/jpeg" style="max-width: 330px; padding-left: 25%;">
<video width="330" autoplay muted playsinline loop id="canvas_url" src="{{ data['canvas_url'] }}" type="video/mp4" style="display: none; padding-left: 10%;"></video>
</div>
<div class="middle">
<p id="name" class="song-text">{{ data['name'] }}</p>
<p id="artist" class="artist-text">{{ data['artist'] }}</p>
<!-- <p id="album" class="song-info">{{ data['album'] }}</p>
<p id="progress_ms">{{ data['progress_ms'] }}</p>
<p id="duration_ms">{{ data['duration_ms'] }}</p> -->
<p>
<div class="buttons">
<a><img id="previous" src="http://127.0.0.1:8888/icons/previous.png" class="buttons-individual"></a>
<a><img id="playpause" src="http://127.0.0.1:8888/icons/play.png" class="buttons-individual"></a>
<a><img id="next" src="http://127.0.0.1:8888/icons/next.png" class="buttons-individual"></a>
<a><img id="like" src="http://127.0.0.1:8888/icons/heart.png" class="buttons-individual" style="display:none;"></a>
</div>
</p>
</div>
<div class="right">
<p id="lyric" class="lyrics">{{ data['lyric'] }}</p>
</div> </div>
</p>
</div> </div>
<div class="right">
<p id="lyric" class="lyrics">{{ data['lyric'] }}</p>
</div>
</div>
<div style="padding-top: 5px;">
<div id="progress_container" class="progress-container">
<div id="progress_bar" class="progress-bar"></div>
</div>
</div>
<script> <script>
let id, is_playing, is_liked, duration_ms, canvas_url, lyrics, progress_ms; let id, is_playing, is_liked, duration_ms, canvas_url, lyrics, progress_ms;
// Function to update the values every second // Function to update the values every second
@@ -244,49 +260,52 @@
const img = document.getElementById('image'); const img = document.getElementById('image');
img.crossOrigin = 'Anonymous'; img.crossOrigin = 'Anonymous';
animatedBackground = document.querySelector('.animated-background'); animatedBackground = document.querySelector('.animated-background');
progressContainer = document.querySelector('.progress-container');
//get property
if (img.complete) { if (img.complete) {
const color = colorThief.getColor(img); const color = colorThief.getColor(img);
// document.body.style.backgroundColor = 'rgb(' + color + ')';
// document.body.style.backgroundColor = 'rgb(' + color + ')';
animatedBackground.style.setProperty('--color', 'rgb(' + color + ')'); animatedBackground.style.setProperty('--color', 'rgb(' + color + ')');
animatedBackground.classList.add('update-color'); progressContainer.style.setProperty('--color', 'rgb(' + color + ')');
getLuminance(color); getLuminance(color);
} else { } else {
img.addEventListener('load', function() { img.addEventListener('load', function() {
const color = colorThief.getColor(img); const color = colorThief.getColor(img);
// document.body.style.backgroundColor = 'rgb(' + color + ')';
animatedBackground.style.setProperty('--color', 'rgb(' + color + ')'); animatedBackground.style.setProperty('--color', 'rgb(' + color + ')');
animatedBackground.classList.add('update-color'); progressContainer.style.setProperty('--color', 'rgb(' + color + ')');
getLuminance(color); getLuminance(color);
}); });
} }
} }
function getLuminance(color) { function getLuminance(color) {
songText = document.querySelector('.song-text');
artistText = document.querySelector('.artist-text');
buttonsDiv = document.querySelector('.buttons');
lyricsDiv = document.querySelector('.lyrics');
if (Math.sqrt(0.299 * (color[0] ** 2) + 0.587 * (color[1] ** 2) + 0.114 * (color[2] ** 2)) > 170) { if (Math.sqrt(0.299 * (color[0] ** 2) + 0.587 * (color[1] ** 2) + 0.114 * (color[2] ** 2)) > 170) {
document.getElementById('name').style.color = 'black'; songText.style.color = 'black';
document.getElementById('artist').style.color = 'black'; artistText.style.color = 'black';
document.getElementById('lyric').style.color = 'black'; buttonsDiv.style.filter = 'invert(100%)';
document.getElementById('previous').style.filter = 'invert(100%)'; lyricsDiv.style.color = 'black';
document.getElementById('playpause').style.filter = 'invert(100%)';
document.getElementById('next').style.filter = 'invert(100%)';
document.getElementById('like').style.filter = 'invert(100%)';
document.getElementById('progress_container').style.backgroundColor = 'rgb(' + color + ')';
darkColor = [color[0] - 75, color[1] - 75, color[2] - 75] darkColor = [color[0] - 75, color[1] - 75, color[2] - 75]
document.getElementById('progress_bar').style.backgroundColor = 'rgb(' + darkColor + ')'; document.getElementById('progress_bar').style.backgroundColor = 'rgb(' + darkColor + ')';
} else { } else {
document.getElementById('name').style.color = 'white'; songText.style.color = 'white';
document.getElementById('artist').style.color = 'white'; artistText.style.color = 'white';
document.getElementById('lyric').style.color = 'white'; buttonsDiv.style.filter = '';
document.getElementById('previous').style.filter = ''; lyricsDiv.style.color = 'white';
document.getElementById('playpause').style.filter = '';
document.getElementById('next').style.filter = '';
document.getElementById('like').style.filter = '';
document.getElementById('progress_container').style.backgroundColor = 'rgb(' + color + ')';
lightColor = [color[0] + 75, color[1] + 75, color[2] + 75] lightColor = [color[0] + 75, color[1] + 75, color[2] + 75]
document.getElementById('progress_bar').style.backgroundColor = 'rgb(' + lightColor + ')'; document.getElementById('progress_bar').style.backgroundColor = 'rgb(' + lightColor + ')';
} }
} }
function openNav() {
document.getElementById('leftpage').style.width = "100%";
document.querySelector('.animated-background').style.marginLeft = "100%";
}
function closeNav() {
document.getElementById('leftpage').style.width = "0";
document.querySelector('.animated-background').style.marginLeft = "0";
}
// function getLuminance() { // function getLuminance() {
// } // }
@@ -351,4 +370,11 @@
}); });
</script> </script>
</body> </body>
<footer>
<div style="padding-top: 5px;">
<div id="progress_container" class="progress-container">
<div id="progress_bar" class="progress-bar"></div>
</div>
</div>
</footer>
</html> </html>

View File

@@ -14,4 +14,7 @@ to js app, but maybe have js app do it from album art, explore which is better.
CANT GET LYRICS VAR TO BE ACCESSED OUTSIDE OF FUNCTION. AHHHH CANT GET LYRICS VAR TO BE ACCESSED OUTSIDE OF FUNCTION. AHHHH
MAKE album/canvas 33.3%, middle 33.3%, lyrics 33.3% to make sure nothing MAKE album/canvas 33.3%, middle 33.3%, lyrics 33.3% to make sure nothing
moves around if the album switches to a canvas moves around if the album switches to a canvas
have animation for going to left side page not push content to the right, have it
move the content (album, controls, song info, etc.) to the bottom with a nice animation.