Widget Examples

Hello, i made here a widget that displays the currently playing song on spotify using the Last.fm API.


Just create a Last.fm account, connect it to Spotify, create a developer account, and get an API key.
You’ll have to paste you user name and api key in the code.
I couldnt make the widget update more frecuently, if someone can just let me know.
//Replace "USER" with you last.fm user and "APIKEY" with the api key for your user.

let url = "http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=USER&api_key=APIKEY&format=json&limit=1" 
let req = new Request(url)
async function createWidget(nowPlaying) {
 
  let widget = new ListWidget()
    // load image
  const coverArt = await loadImage(nowPlaying.recenttracks.track[0].image[3]["#text"])
     widget.backgroundImage = coverArt
     
  widget.addSpacer()
      // set gradient background
  let startColor = new Color("#1c1c1c19")
  let endColor = new Color("#1c1c1cb4")
  let gradient = new LinearGradient()
  gradient.colors = [startColor, endColor]
  gradient.locations = [0.0, 1]
  widget.backgroundGradient = gradient
    widget.backgroundColor = new Color("1c1c1c")
  // add title and artist
    let title = nowPlaying.recenttracks.track[0].name.toLowerCase()
    // capitalize every first character 
    title = title.replace(/\b\w/g, function(c) {
      return c.toUpperCase();
    });
  let titleTxt = widget.addText(title)
  titleTxt.font = Font.boldSystemFont(12)
  titleTxt.textColor = Color.white()
  titleTxt.leftAlignText()
  widget.addSpacer(2)
  
    let artist = nowPlaying.recenttracks.track[0].artist["#text"]
    // capitalize every first character 
    artist = artist.replace(/\b\w/g, function(c) {
      return c.toUpperCase();
    });
  let artistTxt = widget.addText(artist)
  artistTxt.font = Font.systemFont(10)
  artistTxt.textColor = Color.yellow()
  artistTxt.textOpacity = 1
  artistTxt.leftAlignText()
  
  widget.setPadding(8, 15, 10, 5)
  widget.url = nowPlaying.recenttracks.track[0].url
  return widget
}
  
// helper function to load and parse a restful json api
async function loadNowPlaying(coverArt) {
  const req = new Request(url)
  const json = await req.loadJSON()
  
  return json
}
// helper function to download an image from a given url
async function loadImage(imgUrl) {
  const url = imgUrl !== null ? imgUrl : placeholder;
  const req = new Request(url)
  const image = await req.loadImage()
  
  return image
}
const nowPlaying = await loadNowPlaying()
const widget = await createWidget(nowPlaying)
Script.setWidget(widget)
Script.complete()
widget.presentSmall()

5 Likes

Can share your code?

To test the stacks feature I built a Spotify Now Playing widget. It uses the more complex Spotify Authorization Code Flow which is needed to access a user‘s playback information. The widget automatically refreshes expired access tokens. I also built a Siri Shortcut to simplify the initial setup.

Gist and setup instructions:

Caveat:
Even though it’s been a lot of work this widget is more a proof of concept. It will lag behind since it‘s not possible to force an update of widgets and only iOS alone will decide when to refresh.

6 Likes

The Unsplash calendar widget don’t work any more with the pictures.

I think something is wrong with the Unsplash API. If I change the query from “nature” to “nature,water”, it works now.

2 posts were split to a new topic: Calendar & Reminders

Hi, I’m really new to this sorry!
Could anyone write a script for something like this?

I think there was probably some problems hours ago with the API. It’s normal now for me.

If you use the script I posted earlier, there’s a spot where you can add your own code. I used @riverwolf’s greeting code for this:

// Get the current date
const date = new Date()

// Format the greeting (thank you riverwolf)
let greeting = "Good "
if (date.getHours() < 6) {
	greeting = greeting + "night."
} else if (date.getHours() < 12) {
	greeting = greeting + "morning."
} else if (date.getHours() < 17) {
	greeting = greeting + "afternoon."
} else if (date.getHours() < 21) {
	greeting = greeting + "evening."
} else {
	greeting = greeting + "night."
}

// Format the date
let df = new DateFormatter()
df.dateFormat = "EEEE, MMMM d"

// Format the widget
widget.addSpacer(40)

let greetingText = widget.addText(greeting)
greetingText.font = Font.boldSystemFont(36)
greetingText.textColor = Color.white()

let dateText = widget.addText(df.string(date))
dateText.font = Font.regularSystemFont(18)
dateText.textColor = Color.white()

widget.addSpacer()

I think it looks pretty similar:

4 Likes

A post was merged into an existing topic: Radio Paradise Now Playing

Hi, I realise I have been a little quiet on here and missed some replies / questions.

I am working on a couple of ideas, in the meantime I have updated my reddit widget. The standard uses the old method, the new uses stacks and has links to open the post too.

Here is a screenshot of the two side by side:

Code can be found here:

RedditViewer:

RedditViewerStacks:

The parameter is as follows:
apollo@scriptable@1@pic@4
The client to open @ the subreddit @ placeholder - this was for debugging @ whether to show pics (this is to be coded) @ How many entries - this will depend on font sizes ‘ verbosity of posts.

1 Like

30 posts were split to a new topic: OpenWeather Forecast

Thankyou so much!!!

This looks awesome! Getting this error though:

2020-09-30 09:37:21: Error on line 103:25: ReferenceError: Can't find variable: shouldRound

Any ideas?

Hmm :thinking:, that’s strange, since the function is declared near the end of the file.

If someone got it to work, I would appreciate if you share a screenshot, I would like to see it on other devices :hugs:.

@jimmyhartington I was also confused about how to do this - here you go (purple highlights)!

@egamez Love this - thank you! how do we change the units to Fahrenheit :slightly_frowning_face:

found it! just change the units parameter to “imperial” on line 81 as follows:
weatherData = await new Request("https://api.openweathermap.org/data/2.5/onecall?lat=" + LAT + "&lon=" + LON + "&exclude=daily,minutely,alerts&units=imperial&lang=en&appid=" + API_KEY).loadJSON();

here’s how it looks like on my screen.

Looks great on iPad Pro 12.9. Nice work on this Widget!