Advertisement
Guest User

Mini Widget

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