How to create a functioning small thumbnail with small play button with Spotify Apps API? - api

somewhat of a javascript novice here.
I'm trying to create this: http://i.imgur.com/LXFzy.png from the Spotify UI Guidelines.
Basically a 64x64 album cover with an appropriate sized play button.
This is what I have so far:
function DataSource(playlist) {
this.count = function() {
return playlist.length;
}
// make node with cover, trackname, artistname
this.makeNode = function(track_num) {
var t = playlist.data.getTrack(track_num);
// console.log(t);
var li = new dom.Element('li');
//generate cover image with play/pause button
var track = m.Track.fromURI(t.uri, function(a) {
var trackPlayer = new v.Player();
trackPlayer.track;
trackPlayer.context = a;
dom.inject(trackPlayer.node, li, 'top')
});
//track name
var trackName = new dom.Element('p', {
className: 'track',
text: t.name
});
//artist name
var artistName = new dom.Element('p', {
className: 'artist',
text: t.artists[0].name
});
dom.adopt(li, trackName, artistName);
return li;
}
}
This datasource function feeds into a pager function later in the code. This code generates image, artist name and track name just fine except I can't seem to get the image to be 64x64 without overriding with my own css. I'm sure there is a way to set this in javascript since the core Spotify CSS files include a class for it however I'm at a loss at how to do it.
Also the play button renders but gives an error in the console that the track has no method 'get' when I click on it. How am I suppose to know it needs a get? Is there some way I can see this player function so I know what I'm doing wrong with it?
Any help would be greatly appreciated, I'm sure it'll help droves of people too as there is no documentation anywhere I can find on how to do this.

Check the code here: https://github.com/ptrwtts/kitchensink/blob/master/js/player.js
The kitchensink app displays a lot of the Spotify Apps API functionality
For the playback button, I know that it doesn't seem to actually work for single tracks used as the context. It really only works if you use either an Artist, Album, or Playlist context. Not sure why that is.

Related

MVVM pattern in NativeScript - how to use one?

The Problem
I just cannot figure out the view model in NativeScript
I am having a hard time understanding how view-models work in NativeScript. I understand the high level concept - that the MVVM pattern allows us to create observable objects - and our UI is updated when values change.
Here is a simple example:
main-page.js
var createViewModel = require("./main-view-model").createViewModel;
function onNavigatingTo(args) {
var page = args.object;
page.bindingContext = createViewModel();
}
exports.onNavigatingTo = onNavigatingTo;
main-view-model.js
var Observable = require("tns-core-modules/data/observable").Observable;
function getMessage(counter) {
if (counter <= 0) {
return "Hoorraaay! You unlocked the NativeScript clicker achievement!";
} else {
return counter + " taps left";
}
}
function createViewModel() {
var viewModel = new Observable();
viewModel.counter = 42;
viewModel.message = getMessage(viewModel.counter);
viewModel.onTap = function() {
this.counter--;
this.set("message", getMessage(this.counter));
}
return viewModel;
}
exports.createViewModel = createViewModel;
I understand , some what, what is happening. But not everything.
Questions I Have ...
How would you add a new function , for instance, an email validation function? Would it go into the View Model page, or just plain Javscript page?
Let's say I added a new textfield to the UI. I have a tap function. Where does my function go?
So in this case, everything related to the UI should go in the createViewModel function? Is that correct?
I have also seen in sample apps, where the developer doesn't use view models at all - it appears he just creates it as an observable object.
Thank you for looking. I know I am close to understanding, but that bindingContext and the viewmodel has me a bit confused. [ I have read everything in NS docs ]
John
The answer is either of it should work. You may put the validation or tap function in view model or in the code behind file, it's upto you to decide which works best for you.
If you put it in the view model, you will use event binding (tap="{{ functionName }}" Or if you put it in code behind file, you will just export the function name and simply refer the function name on XML (tap="functionName").
By giving this flexibility you are allowed to separate your code, keep the files light weighted.

Custom Soundcloud Widget (api) Player

I'm trying to create a custom player for some Soundcloud tracks. The idea is to hide the Iframe and create a few players to play different tracks. The loading and playing all works fine but I have two challenges.
How do I create a progressbar (SC.Widget.Events.PLAY_PROGRESS)
How do I create a download link?
A snippet from the way I'm coding this:
(function(){
var widgetIframe = document.getElementById('sc-widget'),
widget = SC.Widget(widgetIframe);
widget.bind(SC.Widget.Events.READY, function() {
$('#play').click(function(){
widget.play();
});
}); }());
To bad the OPEN API is closed..
If you are trying to stream tracks using a custom player, I recommend you do not use the widget at all. Rather, use the streaming SDK directly. There are methods there that can do everything you need to load, play, pause, seek, get the current time of the song and more.
To initialize the streaming player, you can do something like:
SC.initialize({
client_id: "<client id>"
});
SC.stream("/tracks/" + song_id).then(function (player) {
player.play();
}
To build the actual progress bar, you can do something inside your stream function like the following (this example uses JQuery but you don't need to):
player.on("time", function () {
var current_time = player.currentTime();
var current_duration = player.options.duration;
$(".scrubber .scrubber_fill").css("width", ((current_time / current_duration) * 100) + "%");
});

Howto refresh lightgallery when dynamicEl has changed

I have different albums, the contents of which I want to show in lightgallery.
My initial call goes like :
$('.dlCms_c_Carousel').lightGallery({
dynamic : true ,
dynamicEl : dlThis.LGDynEl ,
thumbnail : true ,
mode : 'lg-fade' ,
});
This works perfect, but then, when opening another album, I want the one or the other way to refresh such that the new content of dynamicEl is shown.
Is there a way to do it ?
I was trying a
$('.dlCms_c_Carousel').data("lightGallery").destroy(true)
before, but that messed up. I.e. there seemed to be some functionality, but it looked like the lightbox lost some styling and wasn't opaque any more.
Any hints ?
I'm using Waypoint.js for infinite scrolling with lightgallery.
The solution that I found for dynamic refresh was:
var gallery = $(".infinite-container").lightGallery({
selector: '.item'
});
var infinite = new Waypoint.Infinite({
element: document.querySelector('.infinite-container'),
onAfterPageLoad: () => {
gallery.data('lightGallery').destroy(true);
gallery = $(".infinite-container").lightGallery({
selector: '.item'
});
}
});
From my experience, the object returned from the lightgallery initialization has to be used on the destroy.
Hope it helps.

Rendering results from an API after using a search function with Backbone.js

I am new to Backbone.js and I am trying to create an application that can check if you completed the videos games you control.
I am using an API to retrieve any information about videogames.
I want to be able to search for a game, for example "Zelda". It should then list every Zelda game.
I get stuck because I don't know how to get the search function to work properly with the API and I don't know how to render it properly. I have written a template for the games that should render.
I have no clue what to do know, or if I'm even on the right track. I am not asking for someone to code it completely, I am asking for a step in the right direction.
Let me know if you need more code.
library_view.js
var LibraryView = Backbone.View.extend({
el:$("#games"),
url: url = "http://www.giantbomb.com/api/search/?api_key=[KEY]",
events:{
"keypress input":"findGames"
},
findGames:function(e){
if(e.which == 13){
query = $(".searchfield").val()
field_list = "name,platforms"
resources = "game"
url = url +"&query="+ query +"field_list"+ field_list +"resources"+ resources
}
},
index.html
<input type="search" placeholder="Find a game" class="searchfield">
It looks like you are mashing together a View and a Model.
A view, for instance, shouldn't have URL inside it, it doesn't know what to do with it.
The correct path would be something roughly like so:
var SearchModel = Backbone.Model.extend();
var LibraryView = Backbone.View.extend({
el: $("#games"),
events:{
"keypress input":"findGames"
},
findGames: function(e){
// get query, field_list, resources
var searchModel = new SearchModel()
searchModel.fetch({
url: "http://www.giantbomb.com/api/search/?api_key=[KEY]"+"&query="+ query +"field_list"+ field_list +"resources"+ resources
});
// do something with searchModel
}
});
After the fetch, searchModel will hold the data Backbone Model style.
Let's say the returned value from the AJAX call is:
{
"answer": 42
}
Then:
searchModel.get("answer") // = 42
The SearchModel is just an abstraction here as you don't really need it (you can just ajax it). But I put it to help you understand what Model represents, it basically represents only data... It doesn't know what View is.

How to get all artists of a user (Spotify Api 1.x)?

I'm trying to get a list of Artists for a user. It was very easy in the 0.x Api, but now i can't do it.
require([
'$api/models',
'$api/location#Location',
'$api/library#Library',
'$api/search#Search',
'$api/toplists#Toplist',
'$views/buttons',
'$views/list#List',
'$views/image#Image'
], function(models, Location, Library, Search, Toplist, buttons, List, Image) {
var librarys = Library.forCurrentUser();
console.log("LIBRARY", librarys);
librarys.load("artists").done(
function(artists) {
console.log(artists);
artists.load('owner').done(function(snapshot) {
console.log("SNAP",snapshot);
});
});
});
I get a response of "Library.forCurrentUser();" but everything i try next fails. There is no error or something, but either "librarys.load("artists")" nor "librarys.snapshot()" works.
By loading "artists" from the library, you're actually not getting artists back in the callback function, but a library that has loaded the artists. Since you almost never need to have everything loaded, it's better for performance if you specify what you want to have loaded. If you wanted to load tracks as well as artists, simply use "artists", "tracks" as load parameter.
If you want to see the Artists in the current user's library, you can do like so:
require(['$api/library#Library'], function(Library) {
Library.forCurrentUser().load("artists").done(function(library) {
library.artists.snapshot().done(function(snapshot) {
for (var i = 0; i < snapshot.length; i++) {
console.log(snapshot.get(i).name);
}
});
});
});
Hope this helps.
Edit: This is working for the Spotify Apps API version 1.25.1.