Last active
September 23, 2020 07:30
-
-
Save MiracleXYZ/b0380eef6e6c5259a318afaa9478b0f9 to your computer and use it in GitHub Desktop.
An iOS 14 Scriptable Widget to display stats info of Hololive streams.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Configuration: