Advertisement
Guest User

Scriptable Gradient Bar Widget

a guest
May 3rd, 2025
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Variables used by Scriptable.
  2. // These must be at the very top of the file. Do not edit.
  3. // icon-color: deep-green; icon-glyph: seedling;
  4.  
  5. const black = new Color("#1C1C1E");
  6. const white = new Color("#F2F2F7");
  7.  
  8. const bgColor = Color.dynamic(white, black);
  9.  
  10. const widget = new ListWidget();
  11. widget.backgroundColor = bgColor;
  12.  
  13. const data = await new Request("https://opendata.dwd.de/climate_environment/health/alerts/s31fg.json").loadJSON();
  14.  
  15. const last = new Date(data.last_update. match(/\d{4}-\d{2}-\d{2}/)[0]);
  16. last.setHours(0);
  17.  
  18. var date;
  19. if (new Date() < new Date(new Date(last).setDate(last.getDate() + 1))) date = "today";
  20. else if (new Date() < new Date(new Date(last).setDate(last.getDate() + 2))) date = "tomorrow";
  21. else if (new Date() < new Date(new Date(last).setDate(last.getDate() + 3))) date = "dayafter_to";
  22.  
  23. const severityLevels = Object.entries(data.legend)
  24. .filter(([key, value]) => !key.includes("_desc"))
  25. .map(([key, value]) => value)
  26. .sort();
  27.  
  28. const scalePositions = severityLevels.map((_, i) => i / (severityLevels.length - 1));
  29.  
  30. const severity = severityLevels.indexOf(data.content.filter(item => item.region_id === 50)[0].Pollen.Graeser[date]);
  31.  
  32. const iconSize = 42;
  33. const iconSymbol = SFSymbol.named("allergens.fill");
  34.  
  35. iconSymbol.applyFont(Font.systemFont(iconSize));
  36.  
  37. const icon = widget.addImage(iconSymbol.image);
  38. icon.imageSize = new Size(iconSize, iconSize);
  39.  
  40. const textColor = Color.dynamic(black, white);
  41. icon.tintColor = textColor;
  42.  
  43. widget.addSpacer(null);
  44. const text = widget.addText("Gräser");
  45.  
  46. text.font = Font.title1();
  47. text.minimumScaleFactor = 0.75;
  48. text.lineLimit = 1;
  49. text.textColor = textColor;
  50.  
  51. widget.addSpacer(6);
  52.  
  53. const widgetSize = importModule("widgetSize")(config.widgetFamily);
  54.  
  55. // widget padding: Figma/@apple — iOS UI Kit
  56. const scaleWidth = widgetSize.width - 2 * 16;
  57. const scaleHeight = 6;
  58.  
  59. const paddingSize = 4;
  60.  
  61. const scale = widget.addStack();
  62. scale.size = new Size(scaleWidth, scaleHeight);
  63. scale.setPadding(0, -paddingSize, 0, -paddingSize);
  64. scale.cornerRadius = 9999;
  65.  
  66. const lg = new LinearGradient();
  67. lg.startPoint = new Point(0, 0.5);
  68. lg.endPoint = new Point(1, 0.5);
  69. lg.colors = [
  70.     Color.green(),
  71.     Color.yellow(),
  72.     Color.red()
  73. ];
  74. lg.locations = lg.colors.map((_, i) => i / (lg.colors.length - 1));
  75.  
  76. scale.backgroundGradient = lg;
  77.  
  78. const ctx = new DrawContext();
  79. ctx.size = new Size(scaleHeight + paddingSize * 2, scaleHeight);
  80. ctx.respectScreenScale = true;
  81. ctx.opaque = false;
  82.  
  83. const padding = new Rect(0, -paddingSize, ctx.size.width, ctx.size.width);
  84. ctx.setFillColor(bgColor);
  85. ctx.fillEllipse(padding);
  86.  
  87. const indicator = new Rect(paddingSize, 0, ctx.size.height, ctx.size.height);
  88. ctx.setFillColor(textColor);
  89. ctx.fillEllipse(indicator);
  90.  
  91. scale.addSpacer(scalePositions[severity] * scaleWidth - severity / (severityLevels.length - 1) * ctx.size.height);
  92. scale.addImage(ctx.getImage());
  93. severity === severityLevels.length - 1 ? scale.addSpacer(0) : scale.addSpacer(null);
  94.  
  95. // widget.presentSmall();
  96. Script.setWidget(widget);
  97. Script.complete();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement