25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

122 lines
5.0 KiB

  1. "use strict";
  2. var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
  3. exports.__esModule = true;
  4. exports.getSlotMetrics = getSlotMetrics;
  5. var dates = _interopRequireWildcard(require("./dates"));
  6. var getDstOffset = function getDstOffset(start, end) {
  7. return start.getTimezoneOffset() - end.getTimezoneOffset();
  8. };
  9. var getKey = function getKey(min, max, step, slots) {
  10. return "" + +dates.startOf(min, 'minutes') + ("" + +dates.startOf(max, 'minutes')) + (step + "-" + slots);
  11. };
  12. function getSlotMetrics(_ref) {
  13. var start = _ref.min,
  14. end = _ref.max,
  15. step = _ref.step,
  16. timeslots = _ref.timeslots;
  17. var key = getKey(start, end, step, timeslots); // if the start is on a DST-changing day but *after* the moment of DST
  18. // transition we need to add those extra minutes to our minutesFromMidnight
  19. var daystart = dates.startOf(start, 'day');
  20. var daystartdstoffset = getDstOffset(daystart, start);
  21. var totalMin = 1 + dates.diff(start, end, 'minutes') + getDstOffset(start, end);
  22. var minutesFromMidnight = dates.diff(daystart, start, 'minutes') + daystartdstoffset;
  23. var numGroups = Math.ceil(totalMin / (step * timeslots));
  24. var numSlots = numGroups * timeslots;
  25. var groups = new Array(numGroups);
  26. var slots = new Array(numSlots); // Each slot date is created from "zero", instead of adding `step` to
  27. // the previous one, in order to avoid DST oddities
  28. for (var grp = 0; grp < numGroups; grp++) {
  29. groups[grp] = new Array(timeslots);
  30. for (var slot = 0; slot < timeslots; slot++) {
  31. var slotIdx = grp * timeslots + slot;
  32. var minFromStart = slotIdx * step; // A date with total minutes calculated from the start of the day
  33. slots[slotIdx] = groups[grp][slot] = new Date(start.getFullYear(), start.getMonth(), start.getDate(), 0, minutesFromMidnight + minFromStart, 0, 0);
  34. }
  35. } // Necessary to be able to select up until the last timeslot in a day
  36. var lastSlotMinFromStart = slots.length * step;
  37. slots.push(new Date(start.getFullYear(), start.getMonth(), start.getDate(), 0, minutesFromMidnight + lastSlotMinFromStart, 0, 0));
  38. function positionFromDate(date) {
  39. var diff = dates.diff(start, date, 'minutes') + getDstOffset(start, date);
  40. return Math.min(diff, totalMin);
  41. }
  42. return {
  43. groups: groups,
  44. update: function update(args) {
  45. if (getKey(args) !== key) return getSlotMetrics(args);
  46. return this;
  47. },
  48. dateIsInGroup: function dateIsInGroup(date, groupIndex) {
  49. var nextGroup = groups[groupIndex + 1];
  50. return dates.inRange(date, groups[groupIndex][0], nextGroup ? nextGroup[0] : end, 'minutes');
  51. },
  52. nextSlot: function nextSlot(slot) {
  53. var next = slots[Math.min(slots.indexOf(slot) + 1, slots.length - 1)]; // in the case of the last slot we won't a long enough range so manually get it
  54. if (next === slot) next = dates.add(slot, step, 'minutes');
  55. return next;
  56. },
  57. closestSlotToPosition: function closestSlotToPosition(percent) {
  58. var slot = Math.min(slots.length - 1, Math.max(0, Math.floor(percent * numSlots)));
  59. return slots[slot];
  60. },
  61. closestSlotFromPoint: function closestSlotFromPoint(point, boundaryRect) {
  62. var range = Math.abs(boundaryRect.top - boundaryRect.bottom);
  63. return this.closestSlotToPosition((point.y - boundaryRect.top) / range);
  64. },
  65. closestSlotFromDate: function closestSlotFromDate(date, offset) {
  66. if (offset === void 0) {
  67. offset = 0;
  68. }
  69. if (dates.lt(date, start, 'minutes')) return slots[0];
  70. var diffMins = dates.diff(start, date, 'minutes');
  71. return slots[(diffMins - diffMins % step) / step + offset];
  72. },
  73. startsBeforeDay: function startsBeforeDay(date) {
  74. return dates.lt(date, start, 'day');
  75. },
  76. startsAfterDay: function startsAfterDay(date) {
  77. return dates.gt(date, end, 'day');
  78. },
  79. startsBefore: function startsBefore(date) {
  80. return dates.lt(dates.merge(start, date), start, 'minutes');
  81. },
  82. startsAfter: function startsAfter(date) {
  83. return dates.gt(dates.merge(end, date), end, 'minutes');
  84. },
  85. getRange: function getRange(rangeStart, rangeEnd, ignoreMin, ignoreMax) {
  86. if (!ignoreMin) rangeStart = dates.min(end, dates.max(start, rangeStart));
  87. if (!ignoreMax) rangeEnd = dates.min(end, dates.max(start, rangeEnd));
  88. var rangeStartMin = positionFromDate(rangeStart);
  89. var rangeEndMin = positionFromDate(rangeEnd);
  90. var top = rangeEndMin - rangeStartMin < step && !dates.eq(end, rangeEnd) ? (rangeStartMin - step) / (step * numSlots) * 100 : rangeStartMin / (step * numSlots) * 100;
  91. return {
  92. top: top,
  93. height: rangeEndMin / (step * numSlots) * 100 - top,
  94. start: positionFromDate(rangeStart),
  95. startDate: rangeStart,
  96. end: positionFromDate(rangeEnd),
  97. endDate: rangeEnd
  98. };
  99. },
  100. getCurrentTimePosition: function getCurrentTimePosition(rangeStart) {
  101. var rangeStartMin = positionFromDate(rangeStart);
  102. var top = rangeStartMin / (step * numSlots) * 100;
  103. return top;
  104. }
  105. };
  106. }