Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const DEV_MODE = true //for developer only
- const DEV_PREVIEW = "medium" //for developer only (this script is specialy made for a medium sized widget)
- // !!NEW USER INPUT REQUIRED!!
- const API_KEY = "" // enter your openweathermap.com api key
- const FORECAST_DAYS = "3"
- const UNITS = "metric" //metric for celsius and imperial for Fahrenheit
- const stackSize = new Size(0, 65) //0 means its automatic
- const widgetBackground = new Color("#161716") //Widget Background
- const stackBackground = new Color("#222224") //Smaller Container Background
- ////// CREATE WIDGET
- if (config.runsInWidget || DEV_MODE) {
- const date = new Date()
- const dateNow = Date.now()
- let df_Name = new DateFormatter()
- let df_Month = new DateFormatter()
- df_Name.dateFormat = "EEEE"
- df_Month.dateFormat = "MMMM"
- const dayName = df_Name.string(date)
- const dayNumber = date.getDate().toString()
- const monthName = df_Month.string(date)
- // let loc = await Location.current()
- // let lat = loc["latitude"]
- // let lon = loc["longitude"]
- let lat = ""
- let lon = ""
- const weatherURL = `https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${lon}&exclude=current,minutely,alerts&units=${UNITS}&appid=${API_KEY}`
- const weatherRequest = new Request(weatherURL)
- const weatherData = await weatherRequest.loadJSON()
- const dailyForecasts = weatherData.daily
- let dailyNextForecasts = []
- for (const dailyForecast of dailyForecasts) {
- if (dailyNextForecasts.length == FORECAST_DAYS) {
- break
- }
- let dt = removeDigits(dateNow, 3)
- if (dailyForecast.dt >= dt) {
- dailyNextForecasts.push(dailyForecast)
- }
- }
- let widget = new ListWidget()
- widget.backgroundColor = widgetBackground
- widget.setPadding(10, 10, 10, 10)
- //Top Row (Date & Weather)
- let topRow = widget.addStack()
- topRow.layoutHorizontally()
- //Top Row Date
- let dateStack = topRow.addStack()
- dateStack.layoutHorizontally()
- dateStack.centerAlignContent()
- dateStack.setPadding(7, 7, 7, 7)
- dateStack.backgroundColor = stackBackground
- dateStack.cornerRadius = 12
- dateStack.size = stackSize
- dateStack.addSpacer()
- let dayNumberTxt = dateStack.addText(dayNumber)
- dayNumberTxt.font = Font.semiboldSystemFont(32)
- dayNumberTxt.textColor = Color.white()
- dateStack.addSpacer(7)
- let dateTextStack = dateStack.addStack()
- dateTextStack.layoutVertically()
- let monthNameTxt = dateTextStack.addText(monthName.toUpperCase())
- monthNameTxt.font = Font.boldSystemFont(10)
- monthNameTxt.textColor = Color.white()
- let dayNameTxt = dateTextStack.addText(dayName.toUpperCase())
- dayNameTxt.font = Font.semiboldSystemFont(10)
- dayNameTxt.textColor = calendarColor
- dateStack.addSpacer()
- topRow.addSpacer()
- widget.addSpacer()
- // Top Row Daily Weather
- let dailyWeatherStack = topRow.addStack()
- dailyWeatherStack.layoutHorizontally()
- dailyWeatherStack.setPadding(8, 2, 8, 2)
- dailyWeatherStack.backgroundColor = stackBackground
- dailyWeatherStack.cornerRadius = 12
- dailyWeatherStack.size = stackSize
- dailyWeatherStack.centerAlignContent()
- for (const nextForecast of dailyNextForecasts) {
- dailyWeatherStack.addSpacer()
- let dayStack = dailyWeatherStack.addStack()
- dayStack.layoutVertically()
- dayStack.centerAlignContent()
- let hourStack =
- dayStack.addStack()
- hourStack.layoutHorizontally()
- hourStack.centerAlignContent()
- let hourTxt = hourStack.addText(formatDay(nextForecast.dt))
- hourTxt.font = Font.mediumRoundedSystemFont(9)
- hourTxt.textColor = Color.white()
- dayStack.addSpacer(5)
- let iconStack =
- dayStack.addStack()
- iconStack.layoutHorizontally()
- tempStack.centerAlignContent()
- const condition = nextForecast.weather[0].id
- let weatherIcon = iconStack.addImage(addSFS(condition))
- weatherIcon.imageSize = new Size(16, 16)
- dayStack.addSpacer(5)
- let tempStack =
- dayStack.addStack()
- tempStack.layoutHorizontally()
- tempStack.centerAlignContent()
- let tempTxt = tempStack.addText(Math.round(nextForecast.temp.max) + "°C")
- tempTxt.font = Font.mediumRoundedSystemFont(9)
- tempTxt.textColor = Color.white()
- }
- dailyWeatherStack.addSpacer()
- // SFSymbol function
- function addSFS(cond) {
- let symbols = {
- // Thunderstorm
- "2": function () {
- return "cloud.bolt.rain.fill"
- },
- // Drizzle
- "3": function () {
- return "cloud.drizzle.fill"
- },
- // Rain
- "5": function () {
- return (cond == 511) ? "cloud.sleet.fill" : "cloud.rain.fill"
- },
- // Snow
- "6": function () {
- return (cond >= 611 && cond <= 613) ? "cloud.snow.fill" : "snow"
- },
- // Atmosphere
- "7": function () {
- if (cond == 781) {
- return "tornado"
- }
- if (cond == 701 || cond == 741) {
- return "cloud.fog.fill"
- }
- return "sun.haze.fill"
- },
- // Clear and clouds
- "8": function () {
- if (cond == 800) {
- return "sun.max.fill"
- }
- if (cond == 802 || cond == 803) {
- return "cloud.sun.fill"
- }
- return "cloud.fill"
- }
- }
- // Get first condition digit.
- let conditionDigit = Math.floor(cond / 100)
- // Style and return the symbol.
- let sfs = SFSymbol.named(symbols[conditionDigit]())
- sfs.applyFont(Font.systemFont(25))
- return sfs.image
- }
- Script.setWidget(widget)
- if (DEV_MODE) {
- if (DEV_PREVIEW == "small") {
- widget.presentSmall()
- }
- if (DEV_PREVIEW == "medium") {
- widget.presentMedium()
- }
- if (DEV_PREVIEW == "large") {
- widget.presentLarge()
- }
- }
- Script.complete()
- }
- ////// FUNCTIONS
- function removeDigits(x, n) {
- return (x - (x % Math.pow(10, n))) / Math.pow(10, n)
- }
- function formatHours(UNIX_timestamp) {
- var date = new Date(UNIX_timestamp * 1000)
- var hours = date.getHours()
- var ampm = hours >= 12 ? ' PM' : ' AM'
- hours = hours % 12
- hours = hours ? hours : 12
- var strTime = hours.toString() + ampm
- return strTime
- }
- function formatDay(UNIX_timestamp) {
- var date = new Date(UNIX_timestamp * 1000)
- var day = date.getDay()
- var dayStr = ""
- switch (day) {
- case (0):
- dayStr = "SUN"
- break
- case (1):
- dayStr = "MON"
- break
- case (2):
- dayStr = "TUE"
- break
- case (3):
- dayStr = "WED"
- break
- case (4):
- dayStr = "THU"
- break
- case (5):
- dayStr = "FRI"
- break
- case (6):
- dayStr = "SAT"
- break
- }
- return dayStr
- }
- function formatTime(date) {
- let df = new DateFormatter()
- df.useNoDateStyle()
- df.useShortTimeStyle()
- return df.string(date)
- }
- async function getImg(image) {
- let fm = FileManager.iCloud()
- let dir = fm.documentsDirectory()
- let path = fm.joinPath(dir + "/imgs/weather", image)
- let download = await fm.downloadFileFromiCloud(path)
- let isDownloaded = await fm.isFileDownloaded(path)
- if (fm.fileExists(path)) {
- return fm.readImage(path)
- } else {
- console.log("Error: File does not exist.")
- }
- }
- // helper function to download an image from a given url
- async function loadImage(imgUrl) {
- const req = new Request(imgUrl)
- return await req.loadImage()
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement