-
-
Save bsehovac/60da2fa1c541e7aa89cdba1beeb9a584 to your computer and use it in GitHub Desktop.
// Get Team ID from https://www.thesportsdb.com and add it as widget parameter | |
const TEAM_ID = args.widgetParameter || 133987 | |
const DARK_MODE = true | |
const widgetSize = config.widgetFamily || 'medium' | |
const textSize = 9.5 | |
const logoSize = 38 | |
const logoSmallSize = 22 | |
const spacing = { normal: 8, smaller: 6, vs: 5, widget: 10 } | |
const fetchData = async (url, type = 'loadJSON') => { | |
const request = new Request(url) | |
const res = await request[type]() | |
return res | |
} | |
const getTeamData = async id => { | |
const url = 'https://www.thesportsdb.com/api/v1/json/1/lookupteam.php?id=' | |
const teamUrl = url + id | |
const data = (await fetchData(teamUrl)).teams[0] | |
return { | |
image: await fetchData(`${data.strTeamBadge}/preview`, 'loadImage'), | |
stadium: data.strStadium | |
} | |
} | |
const getTeamEvents = async () => { | |
const url = 'https://www.thesportsdb.com/api/v1/json/1/eventsnext.php?id=' | |
const data = await fetchData(url + TEAM_ID) | |
return data.events | |
} | |
const getUpcomingEventData = async event => { | |
const home = await getTeamData(event.idHomeTeam) | |
const away = await getTeamData(event.idAwayTeam) | |
return { | |
competition: event.strLeague, | |
homeLogo: home.image, | |
awayLogo: away.image, | |
homeTeam: event.strHomeTeam, | |
awayTeam: event.strAwayTeam, | |
date: event.strTimestamp, | |
stadium: home.stadium, | |
} | |
} | |
const getRestEventsData = async events => { | |
const output = [] | |
for (const event of events) { | |
const isHomeTeam = event.idHomeTeam ==TEAM_ID | |
const team = await getTeamData(event[isHomeTeam ? 'idAwayTeam' : 'idHomeTeam']) | |
output.push({ | |
competition: event.strLeague, | |
logo: team.image, | |
team: event[isHomeTeam ? 'strAwayTeam' : 'strHomeTeam'], | |
date: event.strTimestamp, | |
stadium: 'stadium', | |
text: isHomeTeam ? 'vs' : 'at', | |
}) | |
} | |
return output | |
} | |
const getFormattedDate = (timestamp, useToday = true) => { | |
const millisPerDay = 24 * 60 * 60 * 1000 | |
const formats = [ | |
"MMM d, yyyy 'at' h:mm a", | |
"'Tomorrow at' h:mm a", | |
"'Today at' h:mm a", | |
] | |
const date = new Date(timestamp) | |
const matchDay = (new Date(date)).setHours(0, 0, 0, 0) | |
const today = (new Date()).setHours(0, 0, 0, 0) | |
const diff = (matchDay - today) / millisPerDay | |
const format = useToday ? (diff < 1 ? 2 : diff < 2 ? 1 : 0) : 0 | |
const dateFormatter = new DateFormatter() | |
dateFormatter.dateFormat = formats[format] | |
return dateFormatter.string(date) | |
} | |
const addText = (el, string, type) => { | |
const text = el.addText(string) | |
text.font = type === 'bold' ? | |
Font.boldSystemFont(textSize * 1.2) : | |
Font.regularSystemFont(textSize) | |
text.textColor = new Color(DARK_MODE ? '#ffffff' : '#000000', 1) | |
text.lineLimit = 1 | |
text.textOpacity = type === 'small' ? 0.5 : 1 | |
text.centerAlignText() | |
} | |
const addImage = (el, src, size = logoSize) => { | |
const image = el.addImage(src) | |
image.imageSize = new Size(size, size) | |
} | |
const addSpacer = (el, type) => { | |
el.addSpacer(spacing[type]) | |
} | |
const addStack = (el, type = 'horizontal', centered = false, size) => { | |
const stack = el.addStack() | |
if (type === 'vertical') stack.layoutVertically() | |
else stack.layoutHorizontally() | |
if (centered) stack.centerAlignContent() | |
if (size) stack.size = size | |
return stack | |
} | |
const addLogos = (el, homeLogo, awayLogo) => { | |
const s = addStack(el, 'horizontal', true) | |
addSpacer(s) | |
addImage(s, homeLogo) | |
addSpacer(s, 'vs') | |
addText(s, 'vs') | |
addSpacer(s, 'vs') | |
addImage(s, awayLogo) | |
addSpacer(s) | |
} | |
const initWidget = () => { | |
const w = new ListWidget() | |
w.backgroundColor = new Color(DARK_MODE ? '#1B1B1B' : '#FFFFFF', 1) | |
w.setPadding( | |
spacing.widget, spacing.widget, | |
spacing.widget, spacing.widget, | |
) | |
return w | |
} | |
const addCenteredText = (el, text, type) => { | |
const s = addStack(el, 'horizontal', true) | |
addSpacer(s) | |
addText(s, text, type) | |
addSpacer(s) | |
} | |
const initUpcomingEvent = (el, event) => { | |
addSpacer(el) | |
addCenteredText(el, event.competition) | |
addSpacer(el, 'normal') | |
addLogos(el, event.homeLogo, event.awayLogo) | |
addSpacer(el, 'normal') | |
addCenteredText(el, event.homeTeam.toUpperCase(), 'bold') | |
addCenteredText(el, event.awayTeam.toUpperCase(), 'bold') | |
addSpacer(el, 'smaller') | |
addCenteredText(el, getFormattedDate(event.date)) | |
addCenteredText(el, event.stadium) | |
addSpacer(el) | |
} | |
const initRestEvents = (el, events) => { | |
events.forEach((data, idx) => { | |
const hs = addStack(el, 'horizontal', true) | |
addText(hs, data.text, 'small') | |
addSpacer(hs, 'vs') | |
addImage(hs, data.logo, logoSmallSize) | |
addSpacer(hs, 'vs') | |
const vs = addStack(hs, 'vertical') | |
addText(vs, data.team.toUpperCase(), 'bold') | |
addText(vs, getFormattedDate(data.date, false), 'small') | |
if (idx < 3) addSpacer(el, 'small') | |
}) | |
} | |
const createNextMatchWidget = async () => { | |
const events = await getTeamEvents() | |
const widget = initWidget() | |
if (widgetSize === 'small') { | |
const upcomingEventData = await getUpcomingEventData(events[0]) | |
initUpcomingEvent(widget, upcomingEventData) | |
} else if (widgetSize === 'medium') { | |
const upcomingEventData = await getUpcomingEventData(events[0]) | |
const restEventData = await getRestEventsData(events.slice(1, 5)) | |
const s = addStack(widget, 'horizontal', true) | |
initUpcomingEvent(addStack(s, 'vertical', true, new Size(130, 135)), upcomingEventData) | |
addSpacer(s, 'normal') | |
initRestEvents(addStack(s, 'vertical', true, new Size(160, 135)), restEventData) | |
} | |
return widget | |
} | |
const widget = await createNextMatchWidget() | |
Script.setWidget(widget) | |
Script.complete() | |
await widget.presentMedium() |
Looks like this is broken due to changes in the api.
From the dev section of sportsdb website. Next 5 events by team api requires Patreon 🙁:
Next 5 Events by Team Id
https://www.thesportsdb.com/api/v1/json/1/eventsnext.php?id=133602 Patreon ONLY
Yeah, if someone finds some free api for soccer, please let me know so I can update the widget. But it has to have Red Star Belgrade available if you want to motivate me. 😅
I couldn't find the api for sure in the fotmob, but I think there is a widget using it.
-> https://github.com/thejosejorge/futcal-for-scriptable
also
-> https://github.com/bgrnwd/fotmob
I think it's possible to use some of it here, like Api. I wish I could be of help.
Since a few days ago I got this message in the script box. How can I fix it?
Error: the data couldn't be read because it isnt in the correct format.
What’s the id for the Los Angeles Rams
Hi,Can i change the widget’s background? Im really bad at that,if you can help me i’ll be grateful and can i change the time zone?