Skip to content

Instantly share code, notes, and snippets.

@MiracleXYZ
Last active September 23, 2020 07:30
Show Gist options
  • Save MiracleXYZ/b0380eef6e6c5259a318afaa9478b0f9 to your computer and use it in GitHub Desktop.
Save MiracleXYZ/b0380eef6e6c5259a318afaa9478b0f9 to your computer and use it in GitHub Desktop.
An iOS 14 Scriptable Widget to display stats info of Hololive streams.
let data = await loadData()
let widget = await createWidget(data)
// Check if the script is running in a widget. If not, show a preview of the widget to easier debug it -> open the stats webpage in Safari.
if (!config.runsInWidget) {
// await widget.presentMedium()
await Safari.open('https://holo.poi.cat/youtube-stream')
}
// Tell the system to show the widget.
Script.setWidget(widget)
Script.complete()
async function createWidget(data) {
let items = data.streams
// Transform the update time into string.
let updatedAt = data.updatedAt
let updatedDate = new Date(Date.parse(updatedAt))
let dateFormatter = new DateFormatter()
dateFormatter.useShortDateStyle()
dateFormatter.useShortTimeStyle()
let updatedStr = dateFormatter.string(updatedDate)
// Determine whether a stream is ongoing or ended.
let ongoingStreams = []
let endedStreams = []
items.forEach((entry) => {
if ('endTime' in entry) {
endedStreams.push(entry)
} else {
if (!('averageViewerCount' in entry)) {
// Set viewer counts to 0 for member-only streams (to make sure they are not displayed).
entry['averageViewerCount'] = 0
entry['maxViewerCount'] = 0
}
ongoingStreams.push(entry)
}
})
// Sort by average viewer count (descending).
ongoingStreamsSorted = ongoingStreams.sort((a, b) => b.averageViewerCount - a.averageViewerCount)
if (ongoingStreams.length > 0) {
var item = ongoingStreamsSorted[0]
} else {
var item = endedStreams[0]
}
let streamer = item.vtuberId
let imgURL = `https://img.youtube.com/vi/${item.streamId}/maxresdefault.jpg`
let rawDate = item["startTime"]
let date = new Date(Date.parse(rawDate))
let strDate = dateFormatter.string(date)
// Set gradient colors. Feel free to change if you want a different color.
// Colors I choose to display the HoloEN widget (2 gradient colors & 1 background color):
// #ff4747e6 #ff4747b3 #ff4747
let gradient = new LinearGradient()
gradient.locations = [0, 1]
gradient.colors = [
new Color("#0fa3dbf7"),
new Color("#0fa3dbd0")
]
let w = new ListWidget()
if (imgURL != null) {
let imgReq = new Request(imgURL)
let img = await imgReq.loadImage()
w.backgroundImage = img
}
w.backgroundColor = new Color("#0fa3db")
w.backgroundGradient = gradient
// Add spacer above content to center it vertically.
w.addSpacer()
// Show title.
let titleTxt = w.addText(item.title)
titleTxt.font = Font.boldSystemFont(16)
titleTxt.textColor = Color.white()
// Add spacing below title.
w.addSpacer(8)
// Show stats info.
let statsTxt = w.addText(`${streamer} · ${strDate} · 🔭 ${item.averageViewerCount} / ${item.maxViewerCount}`)
statsTxt.font = Font.mediumSystemFont(12)
statsTxt.textColor = Color.white()
statsTxt.textOpacity = 0.9
// Add spacing below stats info.
w.addSpacer(2)
// Show number of ongoing streams.
let ongoingTxt = w.addText(`${ongoingStreams.length} streams ongoing`)
ongoingTxt.font = Font.mediumSystemFont(12)
ongoingTxt.textColor = Color.white()
ongoingTxt.textOpacity = 0.9
// Add spacing...
w.addSpacer(2)
// Show footer.
let footer = w.addText(`${updatedStr}, HoloStats`)
footer.font = Font.mediumSystemFont(12)
footer.textColor = Color.white()
footer.textOpacity = 0.9
// footer.rightAlignText()
// Add spacing below content to center it vertically.
w.addSpacer()
return w
}
async function loadData() {
// Change the "ids" parameter if you just want a subset of streamers.
// eg: "...?ids=amelia,calliope,gura,inanis,kiara&startAt=..." (for HololiveEN)
let url = "https://holo.poi.cat/api/v3/youtube_streams?ids=hololive,sora,roboco,miko,suisei,fubuki,matsuri,haato,aki,mel,choco,choco_alt,shion,aqua,subaru,ayame,pekora,rushia,flare,marine,noel,kanata,coco,watame,towa,himemoriluna,lamy,nene,botan,polka,mio,okayu,korone,azki,yogiri,civia,echo,doris,artia,rosalyn,risu,moona,iofi,amelia,calliope,gura,inanis,kiara&startAt=1970-01-01T00:00:00.000Z"
let req = new Request(url)
let json = await req.loadJSON()
return json
}
@MiracleXYZ
Copy link
Author

Configuration:

  • When Interacting: Run Script

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment