Ejemplo n.º 1
0
 private void UpdatePlaylistDetailsUI()
 {
     if (_playlist != null)
     {
         if (_headerParent)
         {
             _headerParent.gameObject.SetActive(true);
         }
         if (_headerImg != null)
         {
             SpotifyAPI.Web.Image image = S4UUtility.GetLowestResolutionImage(_playlist.Images, 300, 300);
             StartCoroutine(S4UUtility.LoadImageFromUrl(image?.Url, (loadedSprite) =>
             {
                 _headerImg.sprite = loadedSprite;
             }));
         }
         if (_headerTitle != null)
         {
             _headerTitle.text = _playlist.Name;
         }
         if (_headerDescription != null)
         {
             _headerDescription.text = _playlist.Description;
         }
         if (_headerDetails != null)
         {
             _headerDetails.text = $"{ _playlist.Owner.DisplayName} • {_playlist.Tracks.Total.Value} songs";
         }
         if (_headerType != null)
         {
             _headerType.text = _playlist.Type.ToUpper();
         }
     }
 }
Ejemplo n.º 2
0
    private void UpdateUI()
    {
        if (_artist != null)
        {
            SetUIActive(true);

            if (_artistName != null)
            {
                _artistName.text = _artist.Name;
            }
            if (_icon != null)
            {
                // Update to target image size
                RectTransform rect = _icon.GetComponent <RectTransform>();
                rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, ImageSize.x);
                rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, ImageSize.y);

                SpotifyAPI.Web.Image lowestResImg = S4UUtility.GetLowestResolutionImage(_artist.Images);
                StartCoroutine(S4UUtility.LoadImageFromUrl(lowestResImg?.Url, (sprite) =>
                {
                    _icon.sprite = sprite;
                }));
            }
        }
        else
        {
            SetUIActive(false);
        }
    }
Ejemplo n.º 3
0
    public override void OnInspectorGUI()
    {
        GUIContent content;

        // Title
        EditorGUILayout.LabelField("General Config", EditorStyles.boldLabel);

        // Client ID
        content          = new GUIContent("Spotify Client ID", "Your client id, found in your Spotify Dashboard. Don't have an id? Go here: https://developer.spotify.com/dashboard/");
        _config.ClientID = EditorGUILayout.TextField(content, _config.ClientID);

        content             = new GUIContent("Redirect URI", "The redirect uri used to pass Spotify authentification onto your app. This exact URI needs to be in your Spotify Dashboard. Dont change this if you don't know what you are doing.");
        _config.RedirectUri = EditorGUILayout.TextField(content, _config.RedirectUri);

        // API scopes
        content = new GUIContent("API Scopes", "All API scopes that will the user will be asked to authorize.");

        List <string> allScopes = S4UUtility.GetAllScopes();

        _selectedScopesFlag = EditorGUILayout.MaskField(content, _selectedScopesFlag, allScopes.ToArray());
        _config.APIScopes   = FlagToAPIScopes(_selectedScopesFlag);

        EditorGUILayout.Space();

        EditorGUILayout.HelpBox("The 'API Scopes' allow you to pick and choose which elements of the API you wish to use. It is recommended to select only the required scopes you need. \n\nFor more information, view the Spotify API guide on authorization scopes (Click the button below)", MessageType.Info);

        if (GUILayout.Button("Scopes Documentation"))
        {
            Application.OpenURL("https://developer.spotify.com/documentation/general/guides/scopes/");
        }

        EditorGUILayout.Space();
    }
Ejemplo n.º 4
0
    public async void Start()
    {
        _loadParent.gameObject.SetActive(true);
        _headerParent.gameObject.SetActive(false);
        _songsParent.gameObject.SetActive(false);

        SpotifyClient client = SpotifyService.Instance.GetSpotifyClient();

        if (client != null)
        {
            Paging <SavedTrack> paging = await client.Library.GetTracks();

            // Load all saved tracks
            _allSavedTracks = await S4UUtility.GetAllOfPagingAsync(client, paging, MaximumLength) as List <SavedTrack>;

            // Only show cwer
            if (_allSavedTracks.Count > MaximumLength)
            {
                _allSavedTracks.RemoveRange(MaximumLength, (_allSavedTracks.Count - 1) - MaximumLength);
            }

            // Load current user to display creator
            PrivateUser profile = await SpotifyService.Instance.GetSpotifyClient().UserProfile.Current();

            _creator = profile.DisplayName;

            _dispatcher.Add(() =>
            {
                UpdateUI();
            });
        }
    }
Ejemplo n.º 5
0
 // Updates the left hand side of the player (Artwork, track name, artists)
 private void UpdatePlayerInfo(string trackName, string artistNames, string artUrl)
 {
     if (_trackName != null)
     {
         _trackName.text = trackName;
     }
     if (_artistsNames != null)
     {
         _artistsNames.text = artistNames;
     }
     if (_trackIcon != null)
     {
         // Load sprite from url
         if (string.IsNullOrEmpty(artUrl))
         {
             _trackIcon.sprite = null;
         }
         else
         {
             StartCoroutine(S4UUtility.LoadImageFromUrl(artUrl, (loadedSprite) =>
             {
                 _trackIcon.sprite = loadedSprite;
             }));
         }
     }
 }
Ejemplo n.º 6
0
    public void StartAuthentification()
    {
        // Check if previous auth
        if (HasPreviousAuthentification())
        {
            // Load local pkce saved token
            _pkceToken = LoadPKCEToken();
            if (_pkceToken != null)
            {
                // Set API authenticator
                SetAuthenticator(_pkceToken);

                // if not expired, output expire time
                if (!_pkceToken.IsExpired)
                {
                    DateTime expireDT = S4UUtility.GetTokenExpiry(_pkceToken.CreatedAt, _pkceToken.ExpiresIn);
                    Debug.Log($"PKCE token loaded | Expires at '{expireDT.ToLocalTime()}'");
                }
            }
        }
        else
        {
            // No previous auth, first time, get new
            GetFreshAuth();
        }
    }
Ejemplo n.º 7
0
 public DateTime GetExpiryDateTime()
 {
     if (_pkceToken != null)
     {
         return(S4UUtility.GetTokenExpiry(_pkceToken.CreatedAt, _pkceToken.ExpiresIn));
     }
     return(DateTime.MinValue);
 }
Ejemplo n.º 8
0
    private void Update()
    {
        CurrentlyPlayingContext context = GetCurrentContext();

        if (context != null)
        {
            // Update current position to context position when user is not dragging
            if (_currentProgressText != null && !_progressStartDrag)
            {
                _currentProgressText.text = S4UUtility.MsToTimeString(context.ProgressMs);
            }

            // Update Volume slider
            if (_volumeSlider != null)
            {
                _volumeSlider.minValue = 0;
                _volumeSlider.maxValue = 100;
                _volumeSlider.value    = context.Device.VolumePercent.Value;
            }

            // Update play/pause btn sprite with correct play/pause sprite
            if (_playPauseButton != null)
            {
                Image playPauseImg = _playPauseButton.transform.GetChild(0).GetComponent <Image>();
                if (context.IsPlaying)
                {
                    playPauseImg.sprite = _pauseSprite;
                }
                else
                {
                    playPauseImg.sprite = _playSprite;
                }
            }

            FullTrack track = context.Item as FullTrack;
            if (track != null)
            {
                if (_totalProgressText != null)
                {
                    _totalProgressText.text = S4UUtility.MsToTimeString(track.DurationMs);
                }
                if (_currentProgressSlider != null)
                {
                    _currentProgressSlider.minValue = 0;
                    _currentProgressSlider.maxValue = track.DurationMs;

                    // Update position when user is not dragging slider
                    if (!_progressStartDrag)
                    {
                        _currentProgressSlider.value = context.ProgressMs;
                    }
                }
            }
        }
    }
Ejemplo n.º 9
0
 private void DownloadUpdateSprite(Image img, List <SpotifyAPI.Web.Image> images)
 {
     if (img != null && img.sprite == null)
     {
         SpotifyAPI.Web.Image icon = S4UUtility.GetLowestResolutionImage(images);
         if (icon != null)
         {
             StartCoroutine(S4UUtility.LoadImageFromUrl(icon.Url, (loadedSprite) =>
             {
                 _icon.sprite = loadedSprite;
             }));
         }
     }
 }
Ejemplo n.º 10
0
    protected override async void OnSpotifyConnectionChanged(SpotifyClient client)
    {
        base.OnSpotifyConnectionChanged(client);

        if (client != null)
        {
            bool isPremium = await S4UUtility.IsUserPremium(client);

            _dispatcher.Add(() =>
            {
                _freeUserWarningParent.SetActive(!isPremium);
            });
        }
    }
Ejemplo n.º 11
0
    private async void PlayingItemChanged(IPlayableItem newPlayingItem)
    {
        if (newPlayingItem == null)
        {
            // No new item playing, reset UI
            UpdatePlayerInfo("No track playing", "No track playing", "");
            SetLibraryBtnIsLiked(false);

            _currentProgressSlider.value = 0;
            _totalProgressText.text      = _currentProgressText.text = "00:00";
        }
        else
        {
            if (newPlayingItem.Type == ItemType.Track)
            {
                if (newPlayingItem is FullTrack track)
                {
                    // Update player information with track info
                    string allArtists          = S4UUtility.ArtistsToSeparatedString(", ", track.Artists);
                    SpotifyAPI.Web.Image image = S4UUtility.GetLowestResolutionImage(track.Album.Images);
                    UpdatePlayerInfo(track.Name, allArtists, image?.Url);

                    // Make request to see if track is part of user's library
                    var client = SpotifyService.Instance.GetSpotifyClient();
                    LibraryCheckTracksRequest request = new LibraryCheckTracksRequest(new List <string>()
                    {
                        track.Id
                    });
                    var result = await client.Library.CheckTracks(request);

                    if (result.Count > 0)
                    {
                        SetLibraryBtnIsLiked(result[0]);
                    }
                }
            }
            else if (newPlayingItem.Type == ItemType.Episode)
            {
                if (newPlayingItem is FullEpisode episode)
                {
                    string creators            = episode.Show.Publisher;
                    SpotifyAPI.Web.Image image = S4UUtility.GetLowestResolutionImage(episode.Images);
                    UpdatePlayerInfo(episode.Name, creators, image?.Url);
                }
            }
        }
    }
Ejemplo n.º 12
0
    protected override async void OnSpotifyConnectionChanged(SpotifyClient client)
    {
        base.OnSpotifyConnectionChanged(client);

        // Check if we have permission to access logged in user's playlists
        if (SpotifyService.Instance.AreScopesAuthorized(Scopes.PlaylistReadPrivate))
        {
            // Get first page from client
            Paging <SimplePlaylist> page = await client.Playlists.CurrentUsers();

            // Get rest of pages from utility function and set variable to run on main thread
            _allPlaylists = await S4UUtility.GetAllOfPagingAsync(client, page);

            _isPopulated = false;
        }
        else
        {
            Debug.LogError($"Not authorized to access '{Scopes.PlaylistReadPrivate}'");
        }
    }
Ejemplo n.º 13
0
    private void UpdateUI()
    {
        if (_playlist != null)
        {
            if (_nameText != null)
            {
                _nameText.text = _playlist.Name;
            }

            if (_creatorText != null)
            {
                _creatorText.text = "By " + _playlist.Owner.DisplayName;
            }

            if (_icon != null)
            {
                SpotifyAPI.Web.Image image = S4UUtility.GetLowestResolutionImage(_playlist.Images);
                if (image != null)
                {
                    StartCoroutine(S4UUtility.LoadImageFromUrl(image.Url, (loadedSprite) =>
                    {
                        _icon.sprite = loadedSprite;
                    }));
                }
            }

            if (_playPlaylistBtn != null)
            {
                _playPlaylistBtn.onClick.AddListener(() =>
                {
                    SpotifyClient client = SpotifyService.Instance.GetSpotifyClient();

                    PlayerResumePlaybackRequest request = new PlayerResumePlaybackRequest
                    {
                        ContextUri = _playlist.Uri
                    };
                    client.Player.ResumePlayback(request);
                });
            }
        }
    }
Ejemplo n.º 14
0
    private void OnTokenRefreshed(object sender, PKCETokenResponse token)
    {
        DateTime expireDT = S4UUtility.GetTokenExpiry(token.CreatedAt, token.ExpiresIn);

        Debug.Log($"PKCE token refreshed | Expires at '{expireDT.ToLocalTime()}'");

        bool triggerEvent = _pkceToken.IsExpired && !token.IsExpired;

        _pkceToken = token;

        if (PKCEConfig != null)
        {
            SavePKCEToken(_pkceToken);
        }

        if (triggerEvent)
        {
            Debug.Log("PKCE: Success in refreshing expired token into new token");
            OnAuthenticatorComplete?.Invoke(_pkceAuthenticator);
        }
    }
Ejemplo n.º 15
0
 private void UpdateUI()
 {
     if (_track != null)
     {
         if (_trackNameText != null)
         {
             _trackNameText.text = _track.Name;
         }
         if (_trackArtistsText != null)
         {
             _trackArtistsText.text = S4UUtility.ArtistsToSeparatedString(", ", _track.Artists);
         }
         if (_albumText != null)
         {
             _albumText.text = _track.Album.Name;
         }
         if (_durationText != null)
         {
             _durationText.text = S4UUtility.MsToTimeString(_track.DurationMs);
         }
     }
 }
Ejemplo n.º 16
0
    /// <summary>
    /// Converts a flag number into the enabled API scopes
    /// </summary>
    /// <param name="flag"></param>
    /// <returns></returns>
    private List <string> FlagToAPIScopes(int flag)
    {
        List <string> allScopes      = S4UUtility.GetAllScopes();
        List <string> selectedScopes = new List <string>();

        // Convert integer into binary string "10010101"
        string binaryString = Convert.ToString(flag, 2);
        // Reverse string so order matches list order
        var array = binaryString.ToCharArray();

        Array.Reverse(array);
        binaryString = new string(array);

        // If binary longer than list, all selected
        if (binaryString.Length > allScopes.Count)
        {
            return(allScopes);           // All selected
        }
        else if (binaryString.Length <= 0)
        {
            return(new List <string>());  // Empty, none selected
        }
        else
        {
            // Iterate through binary string, add scope if it is enabled in bianry string
            for (int i = 0; i < binaryString.Length; i++)
            {
                char currentBinaryValue = binaryString[i];
                if (currentBinaryValue == '1')
                {
                    selectedScopes.Add(allScopes[i]);
                }
            }

            return(selectedScopes);
        }
    }
Ejemplo n.º 17
0
    private void UpdateUI()
    {
        if (_name != null)
        {
            _name.text = _track.Name;
        }
        if (_artist != null)
        {
            _artist.text = S4UUtility.ArtistsToSeparatedString(", ", _track.Artists);
        }
        if (_duration != null)
        {
            _duration.text = S4UUtility.MsToTimeString(_track.DurationMs);
        }
        if (_playBtn != null)
        {
            _playBtn.onClick.AddListener(() =>
            {
                var client = SpotifyService.Instance.GetSpotifyClient();
                if (client != null)
                {
                    PlayerResumePlaybackRequest request = new PlayerResumePlaybackRequest()
                    {
                        //ContextUri = ,        // Play within context of just the individual track
                        Uris = new List <string>()
                        {
                            _track.Uri
                        },
                    };
                    client.Player.ResumePlayback(request);

                    Debug.Log($"Spotify App | Playing searched song '{S4UUtility.ArtistsToSeparatedString(", ", _track.Artists)} - {_track.Name}'");
                }
            });
        }
    }
Ejemplo n.º 18
0
    /// <summary>
    /// Gets a string to display a song and it's properties, separated with a dash. For example, "BLACKPINK - Don't Know What To Do"
    /// </summary>
    /// <param name="currentTrack"></param>
    /// <returns></returns>
    public static string GetTrackString(FullTrack track)
    {
        string artists = S4UUtility.ArtistsToSeparatedString(",", track.Artists);

        return(artists + " - " + track.Name);
    }
Ejemplo n.º 19
0
    private async void FetchLatestPlayer()
    {
        if (_client != null)
        {
            // get the current context on this run
            CurrentlyPlayingContext newContext = await _client.Player.GetCurrentPlayback();

            // Check if not null
            if (newContext != null && newContext.Item != null)
            {
                // Check and cast the item to the correct type
                if (newContext.Item.Type == ItemType.Track)
                {
                    FullTrack currentTrack = newContext.Item as FullTrack;

                    // No previous track or previous item was different type
                    if (_currentItem == null || (_currentItem != null && _currentItem is FullEpisode episode))
                    {
                        Debug.Log($"No prev track or new type | -> '{S4UUtility.GetTrackString(currentTrack)}'");
                        _currentItem = currentTrack;
                        OnPlayingItemChanged?.Invoke(_currentItem);
                    }
                    else if (_currentItem != null && _currentItem is FullTrack lastTrack)
                    {
                        // Check if track name & artists aren't the same
                        if (lastTrack.Name != currentTrack.Name || S4UUtility.HasArtistsChanged(lastTrack.Artists, currentTrack.Artists))
                        {
                            Debug.Log($"Track to new Track | '{S4UUtility.GetTrackString(lastTrack)}' -> '{S4UUtility.GetTrackString(currentTrack)}'");
                            _currentItem = currentTrack;
                            OnPlayingItemChanged?.Invoke(_currentItem);
                        }
                    }
                }
                else if (newContext.Item.Type == ItemType.Episode)
                {
                    FullEpisode currentEpisode = newContext.Item as FullEpisode;

                    // If no previous item or current item is different type
                    if (_currentItem == null || (_currentItem != null && _currentItem is FullTrack track))
                    {
                        Debug.Log($"No prev episode or new type | -> '{currentEpisode.Show.Publisher} {currentEpisode.Name}'");
                        _currentItem = currentEpisode;
                        OnPlayingItemChanged?.Invoke(_currentItem);
                    }
                    else if (_currentItem != null && _currentItem is FullEpisode lastEpisode)
                    {
                        if (lastEpisode.Name != currentEpisode.Name || lastEpisode.Show?.Publisher != currentEpisode.Show?.Publisher)
                        {
                            Debug.Log($"Episode to new Episode | '{lastEpisode.Show.Publisher} {lastEpisode.Name}' -> '{currentEpisode.Show.Publisher} {currentEpisode.Name}'");
                            _currentItem = currentEpisode;
                            OnPlayingItemChanged?.Invoke(_currentItem);
                        }
                    }
                }
            }
            else
            {
                // No context or null current playing item

                // If previous item has been set
                if (_currentItem != null)
                {
                    Debug.Log($"Context null | '{(_currentItem.Type == ItemType.Track ? (_currentItem as FullTrack).Name : (_currentItem as FullEpisode).Name)}' -> ?");
                    _currentItem = null;
                    OnPlayingItemChanged?.Invoke(null);
                }
            }

            _currentContext = newContext;
        }
        else
        {
            // If no client but has a previous item, invoke event
            if (_currentItem != null)
            {
                _currentItem = null;
                OnPlayingItemChanged?.Invoke(null);
            }
        }
    }
Ejemplo n.º 20
0
    private void OnProgressSliderValueChanged(float newValueMs)
    {
        _progressDragNewValue = newValueMs;

        _currentProgressText.text = S4UUtility.MsToTimeString((int)_progressDragNewValue);
    }
Ejemplo n.º 21
0
 private void LogTrackChange(string source)
 {
     Debug.Log($"Spotify App | {source} '{S4UUtility.ArtistsToSeparatedString(", ", _track.Artists)} - {_track.Name}'");
 }