Guest User

Untitled

a guest
Jan 31st, 2023
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 7.28 KB | Source Code | 0 0
  1. // Variables used by Scriptable.
  2. // These must be at the very top of the file. Do not edit.
  3. // icon-color: cyan; icon-glyph: magic;
  4. const GOOGLE_MAPS_API_KEY = "YOUR_API_KEY_HERE";
  5.  
  6. const route_1_label = "Ramos Mejía";
  7. const route_1_origin = "14048, Av. Rivadavia 14000, Ramos Mejía, Provincia de Buenos Aires";
  8. const route_1_destination = "C1198 Buenos Aires";
  9.  
  10. const route_2_label = "Once";
  11. const route_2_origin = "C1198 Buenos Aires";
  12. const route_2_destination = "14048, Av. Rivadavia 14000, Ramos Mejía, Provincia de Buenos Aires";
  13.  
  14. const route_3_label = "Santa Fe (a FaDe)";
  15. const route_3_origin = "Santa Fe - Carlos Jaúregui";
  16. const route_3_destination = "Facultad de Derecho (UBA), Av. Pres. Figueroa Alcorta 2263, C1425 CABA";
  17.  
  18. const route_4_label = "Santa Fe (a Hosp)";
  19. const route_4_origin = "Santa Fe - Carlos Jaúregui";
  20. const route_4_destination = "Hospitales, C1437 CABA";
  21.  
  22. const route_5_label = "Pueyrredon (a Congreso.T)";
  23. const route_5_origin = "Estación Pueyrredón, Av. Sta. Fe 2500, C1015 CABA";
  24. const route_5_destination = "Congreso de Tucuman, Av. Cabildo, Buenos Aires";
  25.  
  26. const route_6_label = "Pueyrredon (a Catedral)";
  27. const route_6_origin = "Estación Pueyrredón, Av. Sta. Fe 2500, C1015 CABA";
  28. const route_6_destination = "Catedral, C1004 CABA";
  29.  
  30. const SUBWAY = "subway";
  31. const RAIL = "rail";
  32.  
  33. const icon_subway = "https://img.icons8.com/material/256/subway.png";
  34. const icon_rail = "https://img.icons8.com/material/256/train.png";
  35.  
  36. const routes = [
  37.   {
  38.     label: route_1_label,
  39.     origin_destination: [
  40.       route_1_origin,
  41.       route_1_destination,
  42.     ],
  43.     modes: [RAIL],
  44.   },
  45.   {
  46.     label: route_2_label,
  47.     origin_destination: [
  48.       route_2_origin,
  49.       route_2_destination,
  50.     ],
  51.     modes: [RAIL],
  52.   },
  53.   {
  54.     label: route_3_label,
  55.     origin_destination: [
  56.       route_3_origin,
  57.       route_3_destination,
  58.     ],
  59.     modes: [SUBWAY],
  60.   },
  61.   {
  62.     label: route_4_label,
  63.     origin_destination: [
  64.       route_4_origin,
  65.       route_4_destination,
  66.     ],
  67.     modes: [SUBWAY],
  68.   },
  69.   {
  70.     label: route_5_label,
  71.     origin_destination: [
  72.       route_5_origin,
  73.       route_5_destination,
  74.     ],
  75.     modes: [SUBWAY],
  76.   },
  77.   {
  78.     label: route_6_label,
  79.     origin_destination: [
  80.       route_6_origin,
  81.       route_6_destination,
  82.     ],
  83.     modes: [SUBWAY],
  84.   },
  85. ];
  86.  
  87.  
  88. // Light-Mode 1st, Dark-Mode 2nd
  89. const colors = {
  90.   widgetBg: Color.dynamic(
  91.     new Color("#EAECED"),
  92.     new Color("#22262C")
  93.   ),
  94.   cellBackgroundColor: Color.dynamic(
  95.     new Color("#D0D2D4"),
  96.     new Color("#3C4044")
  97.   ),
  98.   update: Color.dynamic(
  99.     new Color("#676767"),
  100.     new Color("#A1A1A6")
  101.   ),
  102.   labelTextColor: Color.dynamic(
  103.     new Color("#00204F"),
  104.     new Color("#FFF")
  105.   ),
  106.   cellTextColor: Color.dynamic(
  107.     new Color("#212121"),
  108.     new Color("#FFFFFF")
  109.   ),
  110. };
  111.  
  112. const widget = new ListWidget();
  113. widget.backgroundColor = colors.widgetBg;
  114.  
  115. let mainStack = widget.addStack()
  116.  
  117. let leftStack = mainStack.addStack()
  118. leftStack.layoutVertically()
  119. mainStack.addSpacer(10)
  120.  
  121. let rightStack = mainStack.addStack()
  122. rightStack.layoutVertically()
  123.  
  124. function composeGoogleMapsRequestUrl(origin, destination, modes) {
  125.   return [
  126.     "https://maps.googleapis.com/maps/api/directions/json",
  127.     `?origin=${encodeURIComponent(origin)}`,
  128.     `&destination=${encodeURIComponent(destination)}`,
  129.     "&mode=transit",
  130.     modes[0] == "rail" ? "&transit_mode=rail" : "&transit_mode=subway",
  131.     "&transit_routing_preference=fewer_transfers",
  132.     "&alternatives=false",
  133.     "&avoidWalking=true",
  134.     `&key=${GOOGLE_MAPS_API_KEY}`,
  135.   ].join("");
  136. }
  137.  
  138. async function getStopData(origin, destination, modes) {
  139.   const googleMapsRequestUrl =
  140.     composeGoogleMapsRequestUrl(
  141.       origin,
  142.       destination,
  143.       modes
  144.     );
  145.   const googleMapsRequest = new Request(
  146.     googleMapsRequestUrl
  147.   );
  148.   return googleMapsRequest.loadJSON();
  149. }
  150.  
  151. function getLineColors(route) {
  152.   if (
  153.     route &&
  154.     route.legs &&
  155.     route.legs[0] &&
  156.     route.legs[0].steps
  157.   ) {
  158.     const step = route.legs[0].steps.find(step =>
  159.       step &&
  160.       step.transit_details &&
  161.       step.transit_details.line &&
  162.       step.transit_details.line.color
  163.     )
  164.  
  165.     if (step) {
  166.       return {
  167.         lineColor: new Color(step.transit_details.line.color),
  168.         textColor: new Color(step.transit_details.line.text_color)
  169.       }
  170.     }
  171.   }
  172.  
  173.   return {}
  174. }
  175.  
  176. function getStopTimes(stopData) {
  177.   const routes = stopData.routes.filter((route) => {
  178.     // No Multi Modal Trips
  179.     return (
  180.       route.legs.length === 1 &&
  181.       route.legs[0].steps.length <= 3
  182.     );
  183.   });
  184.  
  185.   const routeTimes = routes.map((route) => {
  186.     const lineColors = getLineColors(route)
  187.     return {
  188.       time: route.legs[0].departure_time != null ? route.legs[0].departure_time.text : "N/A",
  189.       colors: lineColors
  190.     }
  191.   })
  192.  
  193.   return routeTimes;
  194. }
  195.  
  196. function getMethodOfTransportation(route) {
  197.   if (
  198.     route &&
  199.     route.legs &&
  200.     route.legs[0] &&
  201.     route.legs[0].steps
  202.   ) {
  203.     const step = route.legs[0].steps.find(step =>
  204.       step &&
  205.       step.transit_details &&
  206.       step.transit_details.travel_mode
  207.     )
  208.  
  209.     if (step) {
  210.       return step.transit_details.travel_mode
  211.     }
  212.   }
  213.  
  214.  
  215. }
  216.  
  217. function createRouteScheduleStack(stopTimes, _color, label, side) {
  218.   let scheduleLabel = side == "left" ? leftStack.addText(label) : rightStack.addText(label);
  219.   scheduleLabel.textColor = colors.labelTextColor;
  220.   scheduleLabel.font = Font.boldSystemFont(14);
  221.  
  222.   let row = side == "left" ? leftStack.addStack() : rightStack.addStack();
  223.   row.setPadding(4, 0, 0, 0);
  224.  
  225.   stopTimes.forEach(({ time: _time, colors: { lineColor, textColor } }, idx) => {
  226.  
  227.     let cell = row.addStack();
  228.     cell.backgroundColor = lineColor || colors.cellBackgroundColor
  229.     cell.setPadding(1, 2, 1, 2);
  230.     cell.cornerRadius = 4;
  231.  
  232.     // Slice the "am" or "pm" from the time string
  233.     const time = _time.slice(0);
  234.    
  235.     // TIME ACA
  236.     let cellText = cell.addText(time);
  237.     cellText.font = Font.mediumSystemFont(12);
  238.  
  239.     cellText.textColor = textColor || colors.cellTextColor;
  240.  
  241.     // Add some spacing to the right of each cell
  242.     const isLastIteration = idx === stopTimes.length - 1;
  243.  
  244.     if (side === "left") {
  245.       leftStack.addStack(row);
  246.     } else {
  247.       rightStack.addStack(row);
  248.     }
  249.     if (!isLastIteration) {
  250.       row.addText(" ");
  251.     }
  252.   });
  253. }
  254.  
  255. let i = 0;
  256. let len = routes.length;
  257.  
  258. for (i; i < len; i++) {
  259.   const route = routes[i];
  260.   const [origin, destination] = route.origin_destination;
  261.   const modes = routes[i].modes;
  262.  
  263.   side = i % 2 == 0 ? "left" : "right";
  264.  
  265.  
  266.   const stopData = await getStopData(origin, destination, modes);
  267.   const stopTimes = getStopTimes(stopData);
  268.   createRouteScheduleStack(
  269.     stopTimes.slice(0, 3),
  270.     route.color,
  271.     route.label,
  272.     side,
  273.   );
  274. }
  275.  
  276. widget.addSpacer();
  277.  
  278. let lastUpdatedAt =
  279.   "Last updated " + new Date().toLocaleTimeString();
  280. const lastUpdatedAtText = widget.addText(lastUpdatedAt);
  281. lastUpdatedAtText.textColor = colors.updated;
  282. lastUpdatedAtText.font = Font.lightSystemFont(8);
  283.  
  284. // Every 10 minutes
  285. const now = Date.now();
  286. widget.refreshAfterDate = new Date(now + 1000 * 60 * 10);
  287.  
  288. Script.setWidget(widget);
  289. Script.complete();
  290.  
  291. widget.presentMedium();
  292.  
  293.  
  294.  
  295.  
Advertisement
Add Comment
Please, Sign In to add comment