Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
200 changes: 134 additions & 66 deletions Spoti15.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Threading.Tasks;
Expand All @@ -8,6 +8,7 @@
using SpotifyAPI.Web.Enums;
using SpotifyAPI.Web.Models;
using System.Globalization;
using System.IO;

namespace Spoti15
{
Expand Down Expand Up @@ -41,6 +42,7 @@ class Spoti15
private bool cachedLikedTrack = false;
private bool likedSongNotification = false;
private bool unlikedSongNotification = false;
private bool noSongPlayingNotification = false;
private bool showingError = false;
private string errorString = "";
private FullTrack likedOrUnlikedSong;
Expand Down Expand Up @@ -115,25 +117,13 @@ private void CheckInput(object source, EventArgs e)
inControlMenu = lcd.IsButtonPressed(LogiLcd.LcdButton.Mono3);
if(inControlMenu && !seeking)
{
bool btn2InCtlNow = lcd.IsButtonPressed(LogiLcd.LcdButton.Mono2);
if(btn2InCtlNow && !btn2Before)
{
var error = api.PausePlayback();
if(error.HasError())
{
showingError = true;
errorString = error.Error.Message;
hideErrorTimer = new Timer();
hideErrorTimer.Enabled = true;
hideErrorTimer.Interval = 3000;
hideErrorTimer.Tick += OnErrorHidden;
}
}
btn2Before = btn2InCtlNow;

bool btn1InCtlNow = lcd.IsButtonPressed(LogiLcd.LcdButton.Mono1);
if(btn1InCtlNow && !btn1Before)
{
if (cachedPlayback == null || cachedPlayback.Item == null)
{
return;
}
var error = api.SkipPlaybackToNext();
if (error.HasError())
{
Expand All @@ -150,7 +140,20 @@ private void CheckInput(object source, EventArgs e)
bool btn0InCtlNow = lcd.IsButtonPressed(LogiLcd.LcdButton.Mono0);
if(btn0InCtlNow && !btn0Before)
{
var error = api.SkipPlaybackToPrevious();
var error = new ErrorResponse();
if (cachedPlayback == null || cachedPlayback.Item == null)
{
return;
}
if ((double)cachedPlayback.ProgressMs >= 3000)
{
error = api.SeekPlayback(0);
}
else
{
error = api.SkipPlaybackToPrevious();
}

if (error.HasError())
{
showingError = true;
Expand All @@ -165,10 +168,18 @@ private void CheckInput(object source, EventArgs e)
return;
}

if (seeking && !btn2Before && cachedPlayback != null && cachedPlayback.CurrentlyPlayingType != TrackType.Ad)
if ((seeking) && (!btn2Before) && (cachedPlayback != null) && (cachedPlayback.CurrentlyPlayingType != TrackType.Ad))
{
//skip seek position if nothing playing to prevent crash
if (cachedPlayback == null || cachedPlayback.Item == null)
{
return;
}
// set seek position to current
currentSeekPosition = (double)cachedPlayback.ProgressMs / cachedPlayback.Item.DurationMs;
else
{
currentSeekPosition = (double)cachedPlayback.ProgressMs / cachedPlayback.Item.DurationMs;
}
}

btn2Before = seeking;
Expand Down Expand Up @@ -222,12 +233,18 @@ private void CheckInput(object source, EventArgs e)
var thisItem = cachedPlayback;
if(thisItem == null || thisItem.Item == null)
{
noSongPlayingNotification = true;
disableLikedSongNotificationTimer = new Timer();
disableLikedSongNotificationTimer.Enabled = true;
disableLikedSongNotificationTimer.Interval = 5000;
disableLikedSongNotificationTimer.Tick += OnLikedSongNotificationFinished;
btn0Before = btn0Now;
return;
}

if(likedSongNotification || unlikedSongNotification)
if(likedSongNotification || unlikedSongNotification || noSongPlayingNotification)
{
likedSongNotification = unlikedSongNotification = false;
likedSongNotification = unlikedSongNotification = noSongPlayingNotification = false;
btn0Before = btn0Now;
disableLikedSongNotificationTimer.Enabled = false;
return;
Expand All @@ -237,7 +254,7 @@ private void CheckInput(object source, EventArgs e)

likedOrUnlikedSong = thisItem.Item;
ListedItem.Add(likedOrUnlikedSong.Id);
if(cachedLikedTrack)
if (cachedLikedTrack)
{
api.RemoveSavedTracks(ListedItem);
likedSongNotification = false;
Expand Down Expand Up @@ -345,7 +362,7 @@ private void OnErrorHidden(object source, EventArgs e)

private void OnLikedSongNotificationFinished(object source, EventArgs e)
{
likedSongNotification = unlikedSongNotification = false;
likedSongNotification = unlikedSongNotification = noSongPlayingNotification = false;
disableLikedSongNotificationTimer.Enabled = false;
}

Expand Down Expand Up @@ -812,7 +829,7 @@ private void DrawPlaylistStatus(Graphics g)
}
else
{
DrawText(g, 3, "Unknown");
DrawText(g, 0, "Liked Songs"); // refer to line 1043
}
}

Expand Down Expand Up @@ -842,9 +859,17 @@ public void UpdateLcd()
{
if(api == null)
{
// TODO: draw spotify logo
// TODO: draw spotify logo (done)
var spotlogo = new byte[] { 66, 77, 150, 1, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 40, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 14, 0, 0, 196, 14, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 128, 0, 0, 0, 0, 0, 3, 255, 248, 0, 0, 0, 0, 0, 15, 255, 254, 0, 0, 0, 0, 0, 31, 255, 255, 0, 0, 0, 0, 0, 127, 255, 255, 192, 0, 0, 0, 0, 255, 255, 255, 224, 0, 0, 0, 1, 255, 255, 255, 240, 0, 0, 0, 3, 255, 255, 255, 248, 0, 0, 0, 7, 255, 255, 255, 252, 0, 0, 0, 7, 255, 255, 255, 252, 0, 0, 0, 15, 255, 255, 255, 254, 0, 0, 0, 31, 255, 255, 241, 255, 0, 0, 0, 31, 255, 255, 193, 255, 0, 0, 0, 31, 195, 254, 3, 255, 0, 0, 0, 63, 192, 0, 15, 255, 128, 0, 0, 63, 224, 0, 127, 255, 128, 0, 0, 63, 255, 255, 254, 127, 128, 0, 0, 63, 255, 255, 248, 127, 128, 0, 0, 63, 255, 255, 192, 127, 192, 0, 0, 127, 129, 248, 0, 255, 192, 0, 0, 127, 128, 0, 3, 255, 192, 0, 0, 127, 192, 0, 31, 255, 192, 0, 0, 63, 252, 3, 255, 223, 128, 0, 0, 63, 255, 255, 255, 15, 128, 0, 0, 63, 255, 255, 248, 15, 128, 0, 0, 63, 7, 255, 128, 31, 128, 0, 0, 63, 0, 0, 0, 63, 128, 0, 0, 31, 0, 0, 0, 255, 0, 0, 0, 31, 128, 0, 15, 255, 0, 0, 0, 31, 252, 0, 255, 255, 0, 0, 0, 15, 255, 255, 255, 254, 0, 0, 0, 7, 255, 255, 255, 252, 0, 0, 0, 7, 255, 255, 255, 252, 0, 0, 0, 3, 255, 255, 255, 248, 0, 0, 0, 1, 255, 255, 255, 240, 0, 0, 0, 0, 255, 255, 255, 224, 0, 0, 0, 0, 127, 255, 255, 192, 0, 0, 0, 0, 31, 255, 255, 0, 0, 0, 0, 0, 7, 255, 254, 0, 0, 0, 0, 0, 1, 255, 240, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
Bitmap bmp;
using (var ms = new MemoryStream(spotlogo))
{
bmp = new Bitmap(ms);
}
int x = (LogiLcd.MonoWidth / 2) - 43 / 2;
g.Clear(bgColor);
DrawTextScroll(g, 2, "SPOTIFY");
g.DrawImage(bmp, x, 0);
//DrawTextScroll(g, 2, "SPOTI15", bigFont);
}
else if(showingError)
{
Expand Down Expand Up @@ -875,33 +900,45 @@ public void UpdateLcd()

DrawPlaybackStatus(g, false);
}
else if(seeking && cachedPlayback != null && cachedPlayback.Item != null)
else if (noSongPlayingNotification)
{
g.Clear(bgColor);
DrawTextScroll(g, 1, "CANNOT LIKE SONG", bigFont);
DrawTextScroll(g, 3, "Spotify not playing");
}
else if(seeking && cachedPlayback != null)
{
g.Clear(bgColor);
DrawTextScroll(g, 1, "SEEKING", bigFont);

DrawTextScroll(g, 1, "SEEKING");

var posInMs = (int)(cachedPlayback.Item.DurationMs * currentSeekPosition);
DrawTextScroll(g, 3, string.Format("{0:D2}:{1:D2}", posInMs / 60000, (posInMs % 60000) / 1000));
if (cachedPlayback.Item == null)
{
DrawTextScroll(g, 3, "Spotify not playing");
}
else
{
var posInMs = (int)(cachedPlayback.Item.DurationMs * currentSeekPosition);
DrawTextScroll(g, 3, string.Format("{0:D2}:{1:D2}", posInMs / 60000, (posInMs % 60000) / 1000));

// Draw progress bar
g.DrawRectangle(Pens.White, 8, LogiLcd.MonoHeight - 16, (LogiLcd.MonoWidth - 24), 6);
g.FillRectangle(Brushes.White, 8, LogiLcd.MonoHeight - 16, (int)((LogiLcd.MonoWidth - 24) * currentSeekPosition), 6);
// Draw progress bar
g.DrawRectangle(Pens.White, 8, LogiLcd.MonoHeight - 16, (LogiLcd.MonoWidth - 24), 6);
g.FillRectangle(Brushes.White, 8, LogiLcd.MonoHeight - 16, (int)((LogiLcd.MonoWidth - 24) * currentSeekPosition), 6);

g.FillPolygon(Brushes.White, new Point[] {
new Point((LogiLcd.MonoWidth - 19), LogiLcd.MonoHeight - 7),
new Point((LogiLcd.MonoWidth - 19), LogiLcd.MonoHeight - 1),
new Point((LogiLcd.MonoWidth - 14), LogiLcd.MonoHeight - 4)
});
g.FillPolygon(Brushes.White, new Point[] {
new Point((LogiLcd.MonoWidth - 19), LogiLcd.MonoHeight - 7),
new Point((LogiLcd.MonoWidth - 19), LogiLcd.MonoHeight - 1),
new Point((LogiLcd.MonoWidth - 14), LogiLcd.MonoHeight - 4)
});

g.FillPolygon(Brushes.White, new Point[] {
new Point(60, LogiLcd.MonoHeight - 7),
new Point(60, LogiLcd.MonoHeight - 1),
new Point(55, LogiLcd.MonoHeight - 4)
});
g.FillPolygon(Brushes.White, new Point[] {
new Point(60, LogiLcd.MonoHeight - 7),
new Point(60, LogiLcd.MonoHeight - 1),
new Point(55, LogiLcd.MonoHeight - 4)
});

DrawText(g, 6, "OK", iconFont, 8);
DrawPlaylistStatus(g);
DrawText(g, 6, "OK", iconFont, 8);
DrawPlaylistStatus(g);
}
}
else if(inControlMenu && cachedPlayback != null)
{
Expand Down Expand Up @@ -931,25 +968,18 @@ public void UpdateLcd()
new Point(18, LogiLcd.MonoHeight - 4)
});

if (cachedPlayback.IsPlaying)
{
g.FillRectangle(Brushes.White, new Rectangle((LogiLcd.MonoWidth - 58), LogiLcd.MonoHeight - 6, 2, 5));
g.FillRectangle(Brushes.White, new Rectangle((LogiLcd.MonoWidth - 61), LogiLcd.MonoHeight - 6, 2, 5));
}
else
{
g.FillPolygon(Brushes.White, new Point[] {
new Point((LogiLcd.MonoWidth - 64), LogiLcd.MonoHeight - 7),
new Point((LogiLcd.MonoWidth - 64), LogiLcd.MonoHeight - 1),
new Point((LogiLcd.MonoWidth - 59), LogiLcd.MonoHeight - 4)
});
}

DrawTextScroll(g, 1, "UP NEXT", bigFont);

if(cachedPlayback.Context == null)
{

if (cachedPlayback.Item == null)
{
DrawTextScroll(g, 3, "Spotify not playing");
}
else
{
DrawTextScroll(g, 3, "Unknown");
}
}
else if (cachedPlayback.Context.Type == "playlist" && upNextPlaylistTrack != null)
{
Expand Down Expand Up @@ -986,7 +1016,31 @@ public void UpdateLcd()

if(cachedPlayback.Context == null)
{
if (cachedPlayback.Item == null)
{
DrawTextScroll(g, 1, "STOPPED", bigFont);
DrawTextScroll(g, 3, "Spotify not playing");
}
else
{
DrawTextScroll(g, 1, "SINGLE", bigFont);
DrawTextScroll(g, 3, cachedPlayback.Item.Album.Name);
DrawTextScroll(g, 4, GetStringFromArtists(cachedPlayback.Item.Artists.ToArray()));
DrawTextScroll(g, 5, string.Format("Released {0}", cachedPlayback.Item.Album.ReleaseDate));

if (cachedAlbum != null)
{
string genres = GetStringFromGenres(cachedAlbum.Genres.ToArray());
if (genres == "")
{
DrawText(g, 0, string.Format("e {0}", cachedAlbum.Popularity), iconFont, 5, 5);
}
else
{
DrawTextScroll(g, 6, string.Format("{0} - {1} followers", GetStringFromGenres(cachedAlbum.Genres.ToArray()), cachedAlbum.Popularity));
}
}
}
}
else if(cachedPlayback.Context.Type == "playlist")
{
Expand Down Expand Up @@ -1030,9 +1084,15 @@ public void UpdateLcd()

DrawPlaybackStatus(g, true);
}
else if(cachedPlayback.Context.Type == "collection")
{
DrawTextScroll(g, 1, "LIKED SONGS", bigFont); //tested, can't find anything that shows as a "collection" other than liked songs

DrawPlaybackStatus(g, true);
}
else
{
DrawTextScroll(g, 1, cachedPlayback.Context.Type);
DrawTextScroll(g, 1, cachedPlayback.Context.Type, bigFont);
}
}
else
Expand All @@ -1041,11 +1101,14 @@ public void UpdateLcd()
var playback = cachedPlayback;
if (playback == null || playback.Item == null)
{
string currentTime1 = DateTime.Now.ToString("h:mm:ss tt");
Size textSize1 = TextRenderer.MeasureText(currentTime1, mainFont);
DrawText(g, 0, currentTime1, LogiLcd.MonoWidth - textSize1.Width);
if (playback == null)
{
g.Clear(bgColor);
DrawTextScroll(g, 1, "ERROR");
DrawTextScroll(g, 2, "SPOTIFY PLAYBACK NOT DETECTED");
DrawTextScroll(g, 1, "STARTING", bigFont);
DrawTextScroll(g, 3, "Wait for API to initialize");
DoRender();
return;
}
Expand All @@ -1059,11 +1122,16 @@ public void UpdateLcd()
else if (playback.HasError())
{
g.Clear(bgColor);
DrawTextScroll(g, 1, "ERROR");
DrawTextScroll(g, 1, "API ERROR");
DrawTextScroll(g, 2, playback.Error.Message);
DoRender();
return;
}
else
{
DrawTextScroll(g, 1, "NO TRACK INFORMATION", bigFont);
DrawTextScroll(g, 3, "Spotify not playing");
DoRender();
return;
}
}
Expand Down