Guest User

Untitled

a guest
Dec 26th, 2020
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.25 KB | None | 0 0
  1. const { transparent } = importModule('no-background')
  2.  
  3. const widget = new ListWidget()
  4. widget.backgroundImage = await transparent(Script.name())
  5.  
  6. // this Scriptable Widget is coded by Slowlydev (aka r/Sl0wly-edits, r/Slowlydev) and adapted by @marco79
  7.  
  8. const DEV_MODE = true //for developer only
  9. const DEV_PREVIEW = "medium" //for developer only (this script is specialy made for a medium sized widget)
  10.  
  11. const API_KEY = "b07bcc62baf142854c86ac6aaed52729" // enter your openweathermap.com api key
  12. const FORECAST_HOURS = "3"
  13. const UNITS = "metric" //metric for celsius and imperial for Fahrenheit
  14.  
  15. const CALENDAR_URL = "calshow://" //Apple Calendar App, if your favorite app does have a URL scheme feel free to change it
  16. const WEATHER_URL = "" //there is no URL for the Apple Weather App, if your favorite app does feel free to add it
  17.  
  18. const widgetBackground = new Color("#DD0133") //Widget Background
  19. const stackBackground = new Color("#FFFFFF") //Smaller Container Background
  20. const calendarColor = new Color("#EA3323") //Calendar Color
  21.  
  22. const stackSize = new Size(0, 65) //0 means its automatic
  23.  
  24.  
  25. if (config.runsInWidget || DEV_MODE) {
  26.  
  27. const date = new Date()
  28. const dateNow = Date.now()
  29.  
  30. let df_Name = new DateFormatter()
  31. let df_Month = new DateFormatter()
  32. df_Name.dateFormat = "EEEE"
  33. df_Month.dateFormat = "MMM YYY"
  34.  
  35. const dayName = df_Name.string(date)
  36. const dayNumber = date.getDate().toString()
  37. const monthName = df_Month.string(date)
  38.  
  39. // Option 1: uncomment this to use let the script locate you each time (which takes longer and needs more battery)
  40. let loc = await Location.current()
  41. let lat = loc["latitude"]
  42. let lon = loc["longitude"]
  43.  
  44. // Option 2: hard coded longitude/latitude
  45. // let lat = "50.95330938278102"
  46. // let lon = "6.915087611808545"
  47.  
  48. const weatherURL = `https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${lon}&exclude=current,minutely,daily,alerts&units=${UNITS}&appid=${API_KEY}`
  49. const weatherRequest = new Request(weatherURL)
  50. const weaterData = await weatherRequest.loadJSON()
  51. const hourlyForecasts = weaterData.hourly
  52. let nextForecasts = []
  53.  
  54. for (const hourlyForecast of hourlyForecasts) {
  55. if (nextForecasts.length == FORECAST_HOURS) { break }
  56. let dt = removeDigits(dateNow, 3)
  57. if (hourlyForecast.dt > dt) {
  58. nextForecasts.push(hourlyForecast)
  59. }
  60. }
  61.  
  62. const events = await CalendarEvent.today([])
  63.  
  64. let futureEvents = []
  65.  
  66. for (const event of events) {
  67. if (futureEvents.length == 2) { break }
  68. if (event.startDate.getTime() > date.getTime() && !event.isAllDay) {
  69. futureEvents.push(event)
  70. }
  71. }
  72.  
  73. let widget = new ListWidget()
  74. widget.backgroundColor = widgetBackground
  75. widget.setPadding(10, 10, 10, 10)
  76.  
  77. //Top Row (Date & Weather)
  78. let topRow = widget.addStack()
  79. topRow.layoutHorizontally()
  80.  
  81. //Top Row Date
  82. let dateStack = topRow.addStack()
  83. dateStack.layoutHorizontally()
  84. dateStack.centerAlignContent()
  85. dateStack.setPadding(7, 7, 7, 7)
  86.  
  87. dateStack.backgroundColor = stackBackground
  88. dateStack.cornerRadius = 12
  89. dateStack.size = stackSize
  90.  
  91. dateStack.addSpacer()
  92.  
  93. let dayNumberTxt = dateStack.addText(dayNumber + ".")
  94. dayNumberTxt.font = Font.semiboldSystemFont(32)
  95. dayNumberTxt.textColor = Color.black()
  96.  
  97. dateStack.addSpacer(7)
  98.  
  99. let dateTextStack = dateStack.addStack()
  100. dateTextStack.layoutVertically()
  101.  
  102. let monthNameTxt = dateTextStack.addText(monthName.toUpperCase())
  103. monthNameTxt.font = Font.boldSystemFont(10)
  104. monthNameTxt.textColor = Color.black()
  105.  
  106. let dayNameTxt = dateTextStack.addText(dayName)
  107. dayNameTxt.font = Font.boldSystemFont(12)
  108. dayNameTxt.textColor = calendarColor
  109.  
  110. dateStack.addSpacer()
  111.  
  112. topRow.addSpacer()
  113.  
  114. widget.addSpacer()
  115.  
  116. //Top Row Weather
  117. let weatherStack = topRow.addStack()
  118. weatherStack.layoutHorizontally()
  119. weatherStack.centerAlignContent()
  120. weatherStack.setPadding(7, 7, 7, 7)
  121.  
  122. weatherStack.backgroundColor = stackBackground
  123. weatherStack.cornerRadius = 12
  124. weatherStack.size = stackSize
  125. weatherStack.url = WEATHER_URL
  126.  
  127. for (const nextForecast of nextForecasts) {
  128.  
  129. const iconURL = "https://openweathermap.org/img/wn/" + nextForecast.weather[0].icon + "@2x.png"
  130.  
  131. let iconRequest = new Request(iconURL);
  132. let icon = await iconRequest.loadImage();
  133. weatherStack.addSpacer()
  134.  
  135. //Hour Forecast Stack
  136. let hourStack = weatherStack.addStack()
  137. hourStack.layoutVertically()
  138.  
  139. let hourTxt = hourStack.addText(formatAMPM(nextForecast.dt))
  140. hourTxt.centerAlignText()
  141. hourTxt.font = Font.systemFont(10)
  142. hourTxt.textColor = Color.black()
  143. hourTxt.textOpacity = 0.5
  144.  
  145. let weatherIcon = hourStack.addImage(icon)
  146. weatherIcon.centerAlignImage()
  147. weatherIcon.size = new Size(25, 25)
  148.  
  149. let tempTxt = hourStack.addText(" " + Math.round(nextForecast.temp) + "°")
  150. tempTxt.centerAlignText()
  151. tempTxt.font = Font.systemFont(10)
  152. tempTxt.textColor = Color.black()
  153. }
  154.  
  155. weatherStack.addSpacer()
  156.  
  157. //Bottom Row Events
  158. let eventStack = widget.addStack()
  159. eventStack.layoutHorizontally()
  160. eventStack.centerAlignContent()
  161. eventStack.setPadding(7, 7, 7, 7)
  162.  
  163. eventStack.backgroundColor = stackBackground
  164. eventStack.cornerRadius = 12
  165. eventStack.size = stackSize
  166. let eventInfoStack
  167.  
  168. const font = Font.lightSystemFont(20)
  169. let calendarSymbol = SFSymbol.named("calendar")
  170. calendarSymbol.applyFont(font)
  171.  
  172. eventStack.addSpacer(8)
  173.  
  174. let eventIcon = eventStack.addImage(calendarSymbol.image)
  175. eventIcon.imageSize = new Size(20, 20)
  176. eventIcon.resizable = false
  177. eventIcon.centerAlignImage()
  178.  
  179. eventStack.addSpacer(14)
  180. eventStack.url = CALENDAR_URL
  181.  
  182. let eventItemsStack = eventStack.addStack()
  183. eventItemsStack.layoutVertically()
  184.  
  185. if (futureEvents.length != 0) {
  186.  
  187. for (let i = 0; i < futureEvents.length; i++) {
  188.  
  189. let futureEvent = futureEvents[i]
  190. const time = formatTime(futureEvent.startDate) + " to " + formatTime(futureEvent.endDate)
  191. const eventColor = new Color("#" + futureEvent.calendar.color.hex)
  192. eventInfoStack = eventItemsStack.addStack()
  193. eventInfoStack.layoutVertically()
  194.  
  195. let eventTitle = eventItemsStack.addText(futureEvent.title)
  196. eventTitle.font = Font.semiboldSystemFont(12)
  197. eventTitle.textColor = eventColor
  198. eventTitle.lineLimit = 1
  199.  
  200. let eventTime = eventItemsStack.addText(time + ".")
  201. eventTime.font = Font.semiboldMonospacedSystemFont(10)
  202. eventTime.textColor = Color.black()
  203. eventTime.textOpacity = 0.5
  204.  
  205. if (i == 0) {
  206. eventItemsStack.addSpacer(3)
  207. }
  208. }
  209.  
  210. } else {
  211.  
  212. let nothingText = eventStack.addText("You have no upcoming events. Enjoy!")
  213. nothingText.font = Font.semiboldMonospacedSystemFont(12)
  214. nothingText.textColor = Color.black()
  215. nothingText.textOpacity = 0.5
  216.  
  217. }
  218.  
  219. eventStack.addSpacer()
  220. Script.setWidget(widget)
  221.  
  222. if (DEV_MODE) {
  223. if (DEV_PREVIEW == "small") { widget.presentSmall() }
  224. if (DEV_PREVIEW == "medium") { widget.presentMedium() }
  225. if (DEV_PREVIEW == "large") { widget.presentLarge() }
  226. }
  227.  
  228. Script.complete()
  229. }
  230.  
  231. function removeDigits(x, n) { return (x - (x % Math.pow(10, n))) / Math.pow(10, n) }
  232.  
  233. function formatAMPM(UNIX_timestamp) {
  234.  
  235. var date = new Date(UNIX_timestamp * 1000)
  236. var hours = date.getHours()
  237.  
  238. // Option 1: uncomment this for am/pm time with hours from 0-12
  239. var ampm = hours >= 12 ? ' PM' : ' AM'
  240. hours = hours % 12
  241. hours = hours ? hours : 12
  242. var strTime = hours.toString() + ampm
  243.  
  244. // Option 2: german localisation
  245. // var strTime = hours.toString() + ":00"
  246.  
  247. return strTime
  248. }
  249.  
  250. function formatTime(date) {
  251. let df = new DateFormatter()
  252. df.useNoDateStyle()
  253. df.useShortTimeStyle()
  254. return df.string(date)
  255. }
Advertisement
Add Comment
Please, Sign In to add comment