Skip to content

Instantly share code, notes, and snippets.

@MiracleXYZ
Last active September 29, 2020 13:20
Show Gist options
  • Save MiracleXYZ/ec0597a359e22e0bf5c439493b8276e3 to your computer and use it in GitHub Desktop.
Save MiracleXYZ/ec0597a359e22e0bf5c439493b8276e3 to your computer and use it in GitHub Desktop.
An iOS 14 Scriptable Widget to display stats info of Nijisanji streams.
// Set groups. If you want all groups, just set groups to [].
let groups = ['nijisanjip', 'nijisanjiin', 'nijisanjiid', 'nijisanjikr']
// let groups = []
let data = await loadData(groups)
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://hiyoko.sonoj.net/live/')
}
// Tell the system to show the widget.
Script.setWidget(widget)
Script.complete()
async function createWidget(data) {
let items = data
// Transform the update time into string.
let updatedDate = new Date(Date.now())
let dateFormatter = new DateFormatter()
dateFormatter.useShortDateStyle()
dateFormatter.useShortTimeStyle()
let updatedStr = dateFormatter.string(updatedDate)
let item = items[0]
let streamer = item.streamer_name
let imgURL = item.thumbnail_url
let rawDate = item.actual_start_time
let date = new Date(rawDate)
let strDate = dateFormatter.string(date)
let channelType = ''
if (item.ch_type == 1) {
channelType = 'YT'
} else {
channelType = item.ch_id.slice(0, 2)
}
let trendStr = ''
if (!(item.trend_rank == null)) {
trendStr = ` 路 馃敟${item.trend_rank}浣峘
}
// Set gradient colors. Feel free to change if you want a different color.
let gradient = new LinearGradient()
gradient.locations = [0, 1]
gradient.colors = [
new Color("#ef7a03e6"),
new Color("#ef7a03b3")
]
let w = new ListWidget()
if (imgURL != null) {
let imgReq = new Request(imgURL)
let img = await imgReq.loadImage()
w.backgroundImage = img
}
w.backgroundColor = new Color("#ef7a03")
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}${channelType}`)
statsTxt.font = Font.mediumSystemFont(12)
statsTxt.textColor = Color.white()
statsTxt.textOpacity = 0.9
// Add spacing below stats info.
w.addSpacer(2)
// Show stats info.
let statsTxt2 = w.addText(`${item.groups_name} 路 馃敪 ${item.viewers}${trendStr}`)
statsTxt2.font = Font.mediumSystemFont(12)
statsTxt2.textColor = Color.white()
statsTxt2.textOpacity = 0.9
// Add spacing below stats info.
w.addSpacer(2)
// Show number of ongoing streams.
let ongoingTxt = w.addText(`鐝惧湪 ${data.length} 銇儵銈ゃ儢閰嶄俊銇屻亗銈娿伨銇檂)
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}, VNUMA`)
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(groups) {
// let url = "https://hiyoko.sonoj.net/dy-st/30s/6c6cb639-1d2f-4151-81c7-fd877700cf98.json"
let url = "https://hiyoko.sonoj.net/f/avtapi/live/fetch_current_v3"
let req = new Request(url)
req.method = 'POST'
req.headers = {
'Connection': 'keep-alive',
'Content-Length': '0',
'Accept': 'application/json;charset=UTF-8',
'Cache-Cotrol': 'public, max-age=300',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36',
'Origin': 'https://hiyoko.sonoj.net',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Referer': 'https://hiyoko.sonoj.net/live/',
'Accept-Language': 'en;q=0.8',
}
let json = await req.loadJSON()
// console.log(json)
let jsonSorted = json.current_live.sort((a, b) => (b.viewers - a.viewers))
let jsonFiltered = jsonSorted.filter((entry) => {
if (entry.groups == null) {
return false
} else if (groups.length == 0) {
return true
} else {
let included = false
for (const group of groups) {
included = included || entry.groups.includes(group)
}
return included
}
})
return jsonFiltered
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment