Guest User

Mini widget

a guest
Dec 22nd, 2020
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.40 KB | None | 0 0
  1. // this Scriptable Widget is coded by Slowlydev (aka r/Sl0wly-edits, r/Slowlydev) and adapted by @marco79
  2.  
  3. const DEV_MODE = false //for developer only
  4. const DEV_PREVIEW = "medium" //for developer only (this script is specialy made for a medium sized widget)
  5.  
  6.  
  7. const CALENDAR_URL = "calshow://" //Apple Calendar App, if your favorite app does have a URL scheme feel free to change it
  8. const WEATHER_URL = "" //there is no URL for the Apple Weather App, if your favorite app does feel free to add it
  9.  
  10. // Battery Const
  11. const canvSize = 200;
  12. const canvTextSize = 45;
  13. const canvas = new DrawContext();
  14. canvas.opaque = false;
  15. const battCircleRemainColor = new Color('#28cc57'); //Battery remaining color
  16. const battCircleDepletedColor = new Color('#4c4b50'); //Battery depleted color
  17. const battCircleBGColor = new Color('#4c4b50'); //Widget background color
  18. const battCircleTextColor = new Color('#fff'); //Widget text color (use same color as above to hide text)
  19.  
  20. const canvWidth = 24; //Battery circle thickness
  21. const canvRadius = 88; //Battery circle radius
  22.  
  23. canvas.size = new Size(canvSize, canvSize);
  24. canvas.respectScreenScale = true;
  25. const batteryLevel = Device.batteryLevel();
  26.  
  27. // Set to true for an image background, false for no image.
  28. const imageBackground = true
  29.  
  30. // Set to true to reset the widget's background image.
  31. const forceImageUpdate = true
  32.  
  33. const files = FileManager.local()
  34.  
  35. const widget = new ListWidget()
  36.  
  37. if (imageBackground) {
  38.  
  39. // Determine if our image exists and when it was saved.
  40. const path = files.joinPath(files.documentsDirectory(), "weather-cal-image")
  41. const exists = files.fileExists(path)
  42.  
  43. // If it exists and an update isn't forced, use the cache.
  44. if (exists && (config.runsInWidget || !forceImageUpdate)) {
  45. widget.backgroundImage = files.readImage(path)
  46.  
  47. // If it's missing when running in the widget, use a gray background.
  48. } else if (!exists && config.runsInWidget) {
  49. widget.backgroundColor = Color.gray()
  50.  
  51. // But if we're running in app, prompt the user for the image.
  52. } else {
  53. const img = await Photos.fromLibrary()
  54. widget.backgroundImage = img
  55. files.writeImage(path, img)
  56. }
  57.  
  58. // If it's not an image background, show the gradient.
  59. } else {
  60. let gradient = new LinearGradient()
  61. let gradientSettings = await setupGradient()
  62.  
  63. gradient.colors = gradientSettings.color()
  64. gradient.locations = gradientSettings.position()
  65.  
  66. widget.backgroundGradient = gradient
  67. }
  68.  
  69.  
  70. const widgetBackground = widget.backgroundImage
  71. const stackBackground = new Color("#303032") //Smaller Container Background
  72. const calendarColor = new Color("#EA3323") //Calendar Color
  73.  
  74. const stackSize = new Size(0, 60) //0 means its automatic
  75.  
  76. if (config.runsInWidget || DEV_MODE) {
  77.  
  78. const date = new Date()
  79. const dateNow = Date.now()
  80.  
  81. let df_Name = new DateFormatter()
  82. let df_Month = new DateFormatter()
  83. df_Name.dateFormat = "EEEE"
  84. df_Month.dateFormat = "MMMM"
  85.  
  86. const dayName = df_Name.string(date)
  87. const dayNumber = date.getDate().toString()
  88. const monthName = df_Month.string(date)
  89.  
  90. const events = await CalendarEvent.today([])
  91.  
  92. let futureEvents = []
  93.  
  94. for (const event of events) {
  95. if (futureEvents.length == 2) { break }
  96. if (event.startDate.getTime() > date.getTime() && !event.isAllDay) {
  97. futureEvents.push(event)
  98. }
  99. }
  100.  
  101. let widget = new ListWidget()
  102. widget.backgroundImage = widgetBackground
  103. widget.setPadding(0, 6, 0, 6)
  104.  
  105. //Top Row (Date & Weather)
  106. let topRow = widget.addStack()
  107. topRow.layoutHorizontally()
  108.  
  109. //Top Row Date
  110. let dateStack = topRow.addStack()
  111. dateStack.centerAlignContent()
  112. dateStack.setPadding(0, 0, 0, 0)
  113.  
  114. dateStack.backgroundColor = stackBackground
  115. dateStack.cornerRadius = 14
  116. dateStack.size = stackSize
  117.  
  118. dateStack.addSpacer()
  119.  
  120. let dateTextStack = dateStack.addStack()
  121.  
  122. dateTextStack.layoutVertically()
  123. dateTextStack.centerAlignContent()
  124.  
  125.  
  126. let dayNameTxt = dateTextStack.addText(dayName.toUpperCase())
  127. dayNameTxt.centerAlignText()
  128. dayNameTxt.font = Font.boldSystemFont(8)
  129. dayNameTxt.textColor = calendarColor
  130.  
  131. let dayNumberTxt = dateTextStack.addText(dayNumber)
  132. dayNumberTxt.centerAlignText()
  133. dayNumberTxt.font = Font.lightSystemFont(34)
  134. dayNumberTxt.textColor = Color.white()
  135.  
  136.  
  137. dateStack.addSpacer()
  138.  
  139. topRow.addSpacer(28)
  140.  
  141. widget.addSpacer()
  142.  
  143. //Top Row Weather
  144. let weatherStack = topRow.addStack()
  145. weatherStack.layoutHorizontally()
  146. weatherStack.centerAlignContent()
  147. weatherStack.setPadding(0, 8, 0, 0)
  148.  
  149. weatherStack.backgroundColor = stackBackground
  150. weatherStack.cornerRadius = 14
  151. weatherStack.size = stackSize
  152. weatherStack.url = WEATHER_URL
  153.  
  154. drawArc(
  155. Math.floor(batteryLevel * 100 * 3.6),
  156. battCircleRemainColor,
  157. battCircleDepletedColor,
  158. battCircleTextColor,
  159. Math.floor(batteryLevel * 100).toString() + "%",
  160. ""
  161. )
  162.  
  163. weatherStack.addImage(canvas.getImage())
  164.  
  165. weatherStack.addSpacer()
  166.  
  167. //Bottom Row Events
  168. let eventStack = widget.addStack()
  169. eventStack.layoutHorizontally()
  170. eventStack.setPadding(7, 7, 7, 7)
  171. eventStack.centerAlignContent()
  172.  
  173. eventStack.backgroundColor = stackBackground
  174. eventStack.cornerRadius = 14
  175. eventStack.size = stackSize
  176. let eventInfoStack
  177.  
  178. eventStack.addSpacer(1)
  179. eventStack.url = CALENDAR_URL
  180.  
  181. let eventItemsStack = eventStack.addStack()
  182. eventItemsStack.layoutVertically()
  183.  
  184. if (futureEvents.length != 0) {
  185.  
  186. for (let i = 0; i < futureEvents.length; i++) {
  187.  
  188. let futureEvent = futureEvents[i]
  189. const time = formatTime(futureEvent.startDate) + " - " + formatTime(futureEvent.endDate)
  190. const eventColor = new Color("#" + futureEvent.calendar.color.hex)
  191. eventInfoStack = eventItemsStack.addStack()
  192. eventInfoStack.layoutVertically()
  193.  
  194. let eventTitle = eventItemsStack.addText(futureEvent.title)
  195. eventTitle.font = Font.boldRoundedSystemFont(14)
  196. eventTitle.textColor = calendarColor
  197. eventTitle.lineLimit = 1
  198.  
  199. let eventTime = eventItemsStack.addText(time)
  200. eventTime.font = Font.boldRoundedSystemFont(10)
  201. eventTime.textColor = Color.white()
  202.  
  203. if (i == 0) {
  204. eventItemsStack.addSpacer(3)
  205. }
  206. }
  207.  
  208. } else {
  209.  
  210. let nothingText = eventStack.addText("Nessun evento")
  211. nothingText.font = Font.boldRoundedSystemFont(14)
  212. nothingText.textColor = calendarColor
  213. nothingText.textOpacity = 0.5
  214.  
  215. }
  216.  
  217. eventStack.addSpacer()
  218.  
  219. const font = Font.lightSystemFont(20)
  220. let calendarSymbol = SFSymbol.named("calendar")
  221. calendarSymbol.applyFont(font)
  222.  
  223.  
  224. let eventIcon = eventStack.addImage(calendarSymbol.image)
  225. eventIcon.imageSize = new Size(15, 15)
  226. eventIcon.resizable = true
  227. eventIcon.tintColor = Color.white()
  228. eventIcon.rightAlignImage()
  229.  
  230. eventStack.addSpacer(-10)
  231.  
  232. Script.setWidget(widget)
  233.  
  234. if (DEV_MODE) {
  235. if (DEV_PREVIEW == "small") { widget.presentSmall() }
  236. if (DEV_PREVIEW == "medium") { widget.presentMedium() }
  237. if (DEV_PREVIEW == "large") { widget.presentLarge() }
  238. }
  239.  
  240. Script.complete()
  241. }
  242.  
  243. function removeDigits(x, n) { return (x - (x % Math.pow(10, n))) / Math.pow(10, n) }
  244.  
  245. function formatAMPM(UNIX_timestamp) {
  246.  
  247. var date = new Date(UNIX_timestamp * 1000)
  248. var hours = date.getHours()
  249.  
  250. // Option 1: uncomment this for am/pm time with hours from 0-12
  251. // var ampm = hours >= 12 ? 'PM' : 'AM'
  252. // hours = hours % 12
  253. // hours = hours ? hours : 12
  254. // var strTime = hours.toString() + ampm
  255.  
  256. // Option 2: german localisation
  257. var strTime = hours.toString() + ":00"
  258. return strTime
  259. }
  260.  
  261. function formatTime(date) {
  262. let df = new DateFormatter()
  263. df.useNoDateStyle()
  264. df.useShortTimeStyle()
  265. return df.
  266.  
  267. string(date)
  268. }
  269.  
  270.  
  271. function sinDeg(deg) {
  272. return Math.sin((deg * Math.PI) / 180);
  273. }
  274.  
  275. function cosDeg(deg) {
  276. return Math.cos((deg * Math.PI) / 180);
  277. }
  278.  
  279. function drawArc(deg, fillColor, strokeColor, txtColor, text, label) {
  280. let ctr = new Point(canvSize / 2, canvSize / 2),
  281. bgx = ctr.x - canvRadius;
  282. bgy = ctr.y - canvRadius;
  283. bgd = 2 * canvRadius;
  284. bgr = new Rect(bgx, bgy, bgd, bgd);
  285.  
  286. // canvas.opaque = false;
  287.  
  288. canvas.setFillColor(fillColor);
  289. canvas.setStrokeColor(strokeColor);
  290. canvas.setLineWidth(canvWidth);
  291. canvas.strokeEllipse(bgr);
  292.  
  293. for (t = 0; t < deg; t++) {
  294. rect_x = ctr.x + canvRadius * sinDeg(t) - canvWidth / 2;
  295. rect_y = ctr.y - canvRadius * cosDeg(t) - canvWidth / 2;
  296. rect_r = new Rect(rect_x, rect_y, canvWidth, canvWidth);
  297. canvas.fillEllipse(rect_r);
  298. }
  299. // attempt to draw info text
  300. const canvTextRect = new Rect(
  301. 0,
  302. 100 - canvTextSize / 2,
  303. canvSize,
  304. canvTextSize
  305. );
  306. const canvLabelRect = new Rect(
  307. 0,
  308. (100 - canvTextSize / 2)-30,
  309. canvSize,
  310. canvTextSize+5
  311. );
  312. canvas.setTextAlignedCenter();
  313. canvas.setTextColor(txtColor);
  314. canvas.setFont(Font.boldSystemFont(canvTextSize));
  315. canvas.drawTextInRect(text, canvTextRect);
  316. canvas.drawTextInRect(label, canvLabelRect);
  317. // return canvas.getImage()
  318. }
Advertisement
Add Comment
Please, Sign In to add comment