time_table 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascript/time_table/controllers/index.js +1 -1
- data/app/assets/javascript/time_table/controllers/time_table_controller_old.js +105 -464
- data/app/assets/javascript/time_table/controllers/{time_table_controller.js → timetable_controller.js} +118 -29
- data/app/assets/javascript/time_table/helpers/drag_event_state.js +11 -2
- data/app/assets/javascript/time_table/helpers/time_table_renderer.js +36 -25
- data/app/assets/stylesheets/time_table/timetable.css +143 -0
- data/app/helpers/time_table/{time_table_helper.rb → time_table_old_helper.rb} +17 -5
- data/app/helpers/time_table/timetable_calendar_helper.rb +206 -0
- data/app/views/time_table/{_time_table.html.erb → _time_table_old.html.erb} +1 -7
- data/app/views/time_table/_timetable.html.erb +49 -0
- data/lib/time_table/version.rb +1 -1
- metadata +8 -7
- data/app/assets/javascript/time_table/controllers/time_table_controller_pre_time_keeper.js +0 -350
- data/app/assets/stylesheets/time_table/time_table.css +0 -136
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad81747930738c0300910d879c6501a22b748cabbd021b391d16740a8e3743a3
|
4
|
+
data.tar.gz: 3df16ab3010a7e728d42ca28aaddd4a5b83e3091aae029885f27880478815271
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d24f58faced0563345d0fb8d74dd06753bf9bf7624929d6603004a102d867fc366ed1d642f1ef7211cf07e82ed9a05b6ac8672a55fe6ff22b07fa5efbb85008
|
7
|
+
data.tar.gz: 3fc45b3a4bd35dd0602f973281a01962bd23883dbf13cd772c57428a24c7901a6dbb4b2beb4b6d5fbc40d96c55778a9f5e30011489113d33dd3629043e706972
|
@@ -6,7 +6,7 @@ import { application } from "./application"
|
|
6
6
|
// import EngineController from "./engine_controller"
|
7
7
|
// application.register("engine", EngineController)
|
8
8
|
|
9
|
-
const controllers = ["
|
9
|
+
const controllers = ["timetable",];
|
10
10
|
|
11
11
|
controllers.forEach((controller) => {
|
12
12
|
import(`./${controller}_controller.js`).then(( { default: module }) => {
|
@@ -1,42 +1,29 @@
|
|
1
1
|
import { Controller } from "@hotwired/stimulus"
|
2
|
+
import ScrollFrame from "../helpers/scroll_frame.js"
|
3
|
+
import TimeKeeper from "../helpers/time_keeper.js"
|
4
|
+
import DragEventState from "../helpers/drag_event_state.js"
|
5
|
+
import TimeTableRenderer from "../helpers/time_table_renderer.js"
|
2
6
|
|
3
|
-
// Connects to data-controller="dropdown"
|
4
7
|
export default class extends Controller {
|
5
8
|
static targets = ["canvas", "eventsList", "event", "eventName", "eventTime", "timestamp"]
|
6
9
|
|
7
|
-
// static SCOPE = {
|
8
|
-
// days: Symbol("days"),
|
9
|
-
// hours: Symbol("hours"),
|
10
|
-
// minutes: Symbol("minutes"),
|
11
|
-
// seconds: Symbol("seconds")
|
12
|
-
// }
|
13
|
-
|
14
|
-
static UNITS = {
|
15
|
-
hours: 3_600_000,
|
16
|
-
minutes: 60_000,
|
17
|
-
seconds: 1_000
|
18
|
-
}
|
19
|
-
|
20
10
|
connect() {
|
21
|
-
this.
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
this.
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
this.
|
34
|
-
this.metricConversion = this.timeScope / this.timeMetric;
|
35
|
-
|
36
|
-
this.scale = 60;
|
11
|
+
this.timeKeeper = new TimeKeeper({
|
12
|
+
start: new Date(this.element.dataset.timetableStartTime),
|
13
|
+
end: new Date(this.element.dataset.timetableEndTime),
|
14
|
+
scope: this.element.dataset.timetableScope,
|
15
|
+
scale: this.element.dataset.timetableScale,
|
16
|
+
clip: this.element.dataset.timetableClipSize
|
17
|
+
});
|
18
|
+
|
19
|
+
let topPadding = parseInt(window.getComputedStyle(this.element).paddingTop, 10);
|
20
|
+
|
21
|
+
this.scrollFrame = new ScrollFrame(this.element, { origin: topPadding });
|
22
|
+
|
23
|
+
this.dragEvent = null;
|
37
24
|
|
38
25
|
this.eventTargets.forEach((event) => {
|
39
|
-
|
26
|
+
TimeTableRenderer.setSpecialClasses(event);
|
40
27
|
});
|
41
28
|
}
|
42
29
|
|
@@ -44,155 +31,135 @@ export default class extends Controller {
|
|
44
31
|
event.preventDefault();
|
45
32
|
event.stopPropagation();
|
46
33
|
|
47
|
-
|
34
|
+
console.log(event.params.dragEvent);
|
48
35
|
|
49
|
-
|
36
|
+
if(event.params.dragEvent != "rescale" && this.element.dataset.timetableFrozenParam == "true") {
|
37
|
+
return;
|
38
|
+
}
|
50
39
|
|
51
|
-
this.dragEvent
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
40
|
+
this.dragEvent = new DragEventState({
|
41
|
+
type: event.params.dragEvent,
|
42
|
+
scrollFrame: this.scrollFrame,
|
43
|
+
timeKeeper: this.timeKeeper,
|
44
|
+
target: event.currentTarget.closest(".event")
|
45
|
+
});
|
57
46
|
|
58
|
-
this.dragEvent.
|
59
|
-
this.dragEvent.currentFrameY = this.dragEvent.originFrameY;
|
47
|
+
this.dragEvent.captureOriginSnapshot(event);
|
60
48
|
|
61
|
-
this.#setDragEventTarget(event.currentTarget.closest(".event"));
|
62
49
|
this.#setDragEventListeners();
|
63
50
|
}
|
64
51
|
|
65
|
-
stopDragEvent(event) {
|
66
|
-
event.preventDefault();
|
67
|
-
|
68
|
-
this.dragging = false;
|
69
|
-
this.dragEvent = {};
|
70
|
-
|
71
|
-
this.stopScroll();
|
72
|
-
this.#removeDragEventListeners();
|
73
|
-
}
|
74
|
-
|
75
52
|
drag(event) {
|
76
|
-
|
77
|
-
if(this.dragging) {
|
78
|
-
this.dragEvent.frame = this.element.getBoundingClientRect();
|
79
|
-
this.dragEvent.previousScrollY = this.dragEvent.currentScrollY;
|
80
|
-
this.dragEvent.currentScrollY = this.#relativeCursorPosition(event).y;
|
81
|
-
this.dragEvent.currentScrollYTime = this.#timeAtPosition(this.dragEvent.currentScrollY);
|
82
|
-
this.dragEvent.currentFrameY = event.clientY - this.dragEvent.frame.top;
|
83
|
-
this.dragEvent.event = event;
|
53
|
+
if(this.dragEvent) {
|
84
54
|
|
85
|
-
this
|
55
|
+
this.dragEvent.captureSnapshot(event);
|
56
|
+
|
57
|
+
// Calls dragResize, dragMove, dragCreate, etc.
|
58
|
+
this.#invokeDragMethodFor(this.dragEvent.type);
|
86
59
|
|
87
60
|
if(this.dragEvent.type != undefined && this.dragEvent.type != "rescale") {
|
88
|
-
this.
|
61
|
+
this.scrollFrame.checkForScroll(this.dragEvent.current.position, this.handleScroll.bind(this));
|
89
62
|
}
|
90
63
|
}
|
91
64
|
}
|
92
65
|
|
66
|
+
stopDragEvent(event) {
|
67
|
+
event.preventDefault();
|
68
|
+
|
69
|
+
this.dragEvent = null;
|
70
|
+
|
71
|
+
this.scrollFrame.stopScrolling();
|
72
|
+
this.#removeDragEventListeners();
|
73
|
+
}
|
74
|
+
|
75
|
+
|
93
76
|
//////////////////
|
94
77
|
// Drag Methods //
|
95
78
|
//////////////////
|
96
79
|
|
97
80
|
dragCreate(event) {
|
98
|
-
let timeBoundaries = this
|
99
|
-
let
|
100
|
-
|
101
|
-
this.
|
81
|
+
let timeBoundaries = this.timeKeeper.timeBoundaries(this.dragEvent.current.time.clipped, this.dragEvent.origin.time.clipped);
|
82
|
+
let eventElement = TimeTableRenderer.createEventElement(timeBoundaries);
|
83
|
+
|
84
|
+
this.eventsListTarget.appendChild(eventElement);
|
85
|
+
|
86
|
+
this.dragEvent.shift({ type: "resize", target: eventElement });
|
87
|
+
this.handleOverlap(eventElement);
|
102
88
|
}
|
103
89
|
|
104
90
|
dragResize(event) {
|
105
|
-
let timeBoundaries = this
|
106
|
-
|
107
|
-
|
91
|
+
let timeBoundaries = this.timeKeeper.timeBoundaries(this.dragEvent.current.time.clipped, this.dragEvent.origin.target.startTime.real);
|
92
|
+
TimeTableRenderer.updateEventElement(this.dragEvent.target, timeBoundaries);
|
93
|
+
this.handleOverlap(this.dragEvent.target);
|
94
|
+
}
|
108
95
|
|
109
96
|
dragMove(event) {
|
110
|
-
let timeChange = (this.dragEvent.
|
111
|
-
let updatedStartTime = new Date(this.dragEvent.
|
112
|
-
let updatedEndTime = new Date(this.dragEvent.
|
97
|
+
let timeChange = (this.dragEvent.current.time.clipped - this.dragEvent.origin.time.clipped);
|
98
|
+
let updatedStartTime = new Date(this.dragEvent.origin.target.startTime.real.getTime() + timeChange)
|
99
|
+
let updatedEndTime = new Date(this.dragEvent.origin.target.endTime.real.getTime() + timeChange);
|
113
100
|
|
114
|
-
let timeBoundaries = this
|
101
|
+
let timeBoundaries = this.timeKeeper.timeBoundaries(updatedStartTime, updatedEndTime);
|
115
102
|
|
116
|
-
|
103
|
+
TimeTableRenderer.updateEventElement(this.dragEvent.target, timeBoundaries);
|
104
|
+
this.handleOverlap(this.dragEvent.target);
|
117
105
|
}
|
118
106
|
|
119
107
|
dragRescale(event) {
|
120
|
-
let delta = this.dragEvent.
|
121
|
-
|
122
|
-
let newScale = Math.max(30, Math.min(300, this.scale - (delta)));
|
108
|
+
let delta = this.dragEvent.previous.position.scroll.y - this.dragEvent.current.position.scroll.y;
|
109
|
+
let newScale = Math.max(30, Math.min(300, this.timeKeeper.scale - (delta)));
|
123
110
|
this.element.style.setProperty("--hour-scale", newScale);
|
124
|
-
let scaleChange = newScale / this.scale;
|
111
|
+
let scaleChange = newScale / this.timeKeeper.scale;
|
125
112
|
|
126
|
-
this.
|
127
|
-
this.scale = newScale;
|
128
|
-
this.setClipSize(newScale);
|
113
|
+
this.timeKeeper.rescale(newScale);
|
129
114
|
|
130
115
|
this.eventTargets.forEach((event) => {
|
131
116
|
event.style.setProperty("height", `${event.offsetHeight * (scaleChange)}px`);
|
132
117
|
event.style.setProperty("top", `${event.offsetTop * (scaleChange)}px`);
|
133
|
-
|
118
|
+
TimeTableRenderer.setSpecialClasses(event);
|
134
119
|
});
|
135
120
|
}
|
136
121
|
|
122
|
+
handleOverlap(element) {
|
123
|
+
let eventTop = element.offsetTop;
|
124
|
+
let eventBottom = eventTop + element.offsetHeight;
|
125
|
+
|
126
|
+
this.eventTargets.forEach((event) => {
|
127
|
+
if(event != element) {
|
128
|
+
let top = event.offsetTop;
|
129
|
+
let bottom = top + event.offsetHeight;
|
130
|
+
|
131
|
+
if(eventTop >= top && eventBottom <= bottom) {
|
132
|
+
element.style.setProperty("left", "50px");
|
133
|
+
event.style.setProperty("right", "20px");
|
134
|
+
} else if(eventTop < bottom && eventBottom > top) {
|
135
|
+
element.style.setProperty("left", "50%");
|
136
|
+
event.style.setProperty("right", "50%");
|
137
|
+
} else {
|
138
|
+
element.style.setProperty("left", "50px");
|
139
|
+
event.style.setProperty("right", "20px");
|
140
|
+
}
|
141
|
+
}
|
142
|
+
});
|
143
|
+
}
|
144
|
+
|
145
|
+
|
146
|
+
|
137
147
|
////////////////////
|
138
148
|
// Scroll Methods //
|
139
149
|
////////////////////
|
140
150
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
let distance = Math.abs(this.dragEvent.currentFrameY - (this.dragEvent.frame.height - 30));
|
149
|
-
let direction = +1;
|
150
|
-
this.setScroll(distance, direction);
|
151
|
-
} else {
|
152
|
-
this.stopScroll();
|
151
|
+
handleScroll(status) {
|
152
|
+
if(status == "ABOVE") {
|
153
|
+
console.log("ABOVE");
|
154
|
+
this.insertTimestampAbove();
|
155
|
+
} else if (status == "BELOW") {
|
156
|
+
console.log("BELOW");
|
157
|
+
this.insertTimestampBelow();
|
153
158
|
}
|
154
|
-
}
|
155
159
|
|
156
|
-
|
157
|
-
{ max: 30, speed: 1 },
|
158
|
-
{ max: 50, speed: 2 },
|
159
|
-
{ max: 100, speed: 3 },
|
160
|
-
{ max: 150, speed: 5 },
|
161
|
-
{ max: 250, speed: 10 },
|
162
|
-
{ max: Infinity, speed: 15}
|
163
|
-
]
|
164
|
-
|
165
|
-
setScroll(distance, direction) {
|
166
|
-
this.scrollEvent.step = (this.constructor.SCROLL_SPEEDS.find(range => distance < range.max)?.speed || 10) * direction;
|
167
|
-
|
168
|
-
// if(distance < 30) {
|
169
|
-
// this.scrollEvent.step = 1 * direction;
|
170
|
-
// } else if(distance < 50) {
|
171
|
-
// this.scrollEvent.step = 2 * direction;
|
172
|
-
// } else if(distance < 70) {
|
173
|
-
// this.scrollEvent.step = 3 * direction;
|
174
|
-
// }
|
175
|
-
|
176
|
-
if(!this.scrollEvent.timeout) {
|
177
|
-
this.scroll();
|
178
|
-
}
|
160
|
+
this.drag(this.dragEvent.current.event);
|
179
161
|
}
|
180
162
|
|
181
|
-
scroll() {
|
182
|
-
this.scrollEvent.timeout = setTimeout(() => {
|
183
|
-
this.element.scrollTop += this.scrollEvent.step;
|
184
|
-
if(this.element.scrollTop == 0) {
|
185
|
-
this.insertTimestampAbove();
|
186
|
-
}
|
187
|
-
|
188
|
-
if(this.element.scrollTop + this.element.clientHeight >= this.scrollHeight) {
|
189
|
-
this.insertTimestampBelow();
|
190
|
-
}
|
191
|
-
|
192
|
-
this.scroll();
|
193
|
-
this.drag(this.dragEvent.event);
|
194
|
-
}, 1);
|
195
|
-
}
|
196
163
|
|
197
164
|
insertTimestampAbove() {
|
198
165
|
}
|
@@ -200,172 +167,11 @@ export default class extends Controller {
|
|
200
167
|
insertTimestampBelow() {
|
201
168
|
// this.dragEvent.inserting = true;
|
202
169
|
// Add 1 hour
|
203
|
-
let time = new Date(this.endTime.getTime());
|
170
|
+
let time = new Date(this.timeKeeper.endTime.getTime());
|
204
171
|
time.setHours(time.getHours() + 1);
|
205
|
-
this.endTime = time;
|
206
|
-
let timestampDiv =
|
207
|
-
console.log(timestampDiv);
|
172
|
+
this.timeKeeper.endTime = time;
|
173
|
+
let timestampDiv = TimeTableRenderer.timestamp(time);
|
208
174
|
this.element.querySelector(".timestamps").appendChild(timestampDiv);
|
209
|
-
this.scrollHeight = this.element.scrollHeight - 20;
|
210
|
-
}
|
211
|
-
|
212
|
-
timestamp(time) {
|
213
|
-
let timestampDiv = document.createElement("div");
|
214
|
-
timestampDiv.classList.add("timestamp");
|
215
|
-
timestampDiv.classList.add("out-of-bounds");
|
216
|
-
timestampDiv.setAttribute("data-time-table-target", "timestamp");
|
217
|
-
timestampDiv.setAttribute("data-action", "mousedown->time-table#startDragEvent");
|
218
|
-
timestampDiv.setAttribute("data-time-table-drag-event-param", "rescale");
|
219
|
-
|
220
|
-
timestampDiv.innerHTML = `
|
221
|
-
<div class="label" data-action="mousedown->time-table#startDragEvent" data-time-table-drag-event-param="rescale">
|
222
|
-
${this.#timeString(time, "short")}
|
223
|
-
</div>
|
224
|
-
`;
|
225
|
-
|
226
|
-
return timestampDiv;
|
227
|
-
}
|
228
|
-
|
229
|
-
stopScroll() {
|
230
|
-
if(this.scrollEvent.timeout) {
|
231
|
-
clearTimeout(this.scrollEvent.timeout);
|
232
|
-
this.scrollEvent = {};
|
233
|
-
}
|
234
|
-
}
|
235
|
-
|
236
|
-
/////////////////////
|
237
|
-
// Time & Position //
|
238
|
-
/////////////////////
|
239
|
-
|
240
|
-
#relativeCursorPosition(event) {
|
241
|
-
return {
|
242
|
-
x: event.clientX - this.dragEvent.frame.left,
|
243
|
-
y: (event.clientY - this.dragEvent.frame.top - 20) + this.element.scrollTop
|
244
|
-
};
|
245
|
-
}
|
246
|
-
|
247
|
-
#relativeElementPosition(element) {
|
248
|
-
let rect = element.getBoundingClientRect();
|
249
|
-
return {
|
250
|
-
x: rect.left - this.dragEvent.frame.left,
|
251
|
-
y: (rect.top - this.dragEvent.frame.top - 20) + this.element.scrollTop
|
252
|
-
};
|
253
|
-
}
|
254
|
-
|
255
|
-
#timeBoundaries(timeA, timeB) {
|
256
|
-
let startTime = new Date(Math.min(timeA, timeB));
|
257
|
-
let endTime = new Date(Math.max(timeA, timeB));
|
258
|
-
|
259
|
-
if (endTime - startTime < this.clipSize * 60 * 1000) {
|
260
|
-
endTime = new Date(startTime.getTime() + (this.clipSize * 60 * 1000));
|
261
|
-
}
|
262
|
-
|
263
|
-
return { start: startTime, end: endTime };
|
264
|
-
}
|
265
|
-
|
266
|
-
#oldTimeAtPosition(y) {
|
267
|
-
let realSecond = ((y / this.scrollHeight) * this.duration) + 1;
|
268
|
-
let clippedSecond = (Math.floor((realSecond / 60).toFixed(0) / this.clipSize) * this.clipSize) * 60;
|
269
|
-
|
270
|
-
// No need for seconds and minutes, should convert to one unit only, probably seconds or milliseconds
|
271
|
-
return {
|
272
|
-
real: new Date(this.startTime.getTime() + (realSecond * 1000)), // For some reason 1 second is added to real each time you change it.
|
273
|
-
clipped: new Date(this.startTime.getTime() + (clippedSecond * 1000)),
|
274
|
-
}
|
275
|
-
}
|
276
|
-
|
277
|
-
#timeAtPosition(y) {
|
278
|
-
let scopeOrdinal = Math.trunc(y / this.scale); // Eg "Hours from start"
|
279
|
-
let positionInScope = (y % this.scale) / this.scale;
|
280
|
-
let scopeMeasure = Math.trunc(positionInScope * this.metricConversion)
|
281
|
-
let clippedScopeMeasure = Math.floor(scopeMeasure / this.clipSize) * this.clipSize;
|
282
|
-
let millisecondsFromStart = (scopeOrdinal * this.timeScope) + (scopeMeasure * this.timeMetric);
|
283
|
-
let clippedMillisecondsFromStart = (scopeOrdinal * this.timeScope) + (clippedScopeMeasure * this.timeMetric);
|
284
|
-
|
285
|
-
return {
|
286
|
-
real: new Date(this.startTime.getTime() + millisecondsFromStart), // For some reason 1 second is added to real each time you change it.
|
287
|
-
clipped: new Date(this.startTime.getTime() + clippedMillisecondsFromStart),
|
288
|
-
}
|
289
|
-
}
|
290
|
-
|
291
|
-
#positionOfTime(time) {
|
292
|
-
let timeFromStart = time - this.startTime;
|
293
|
-
let scopeFromStart = Math.floor(timeFromStart / this.timeScope);
|
294
|
-
let metricFromScope = Math.floor((timeFromStart % this.timeScope) / this.timeMetric);
|
295
|
-
let pixelsFromStart = (scopeFromStart * this.scale) + (metricFromScope * this.scale / this.metricConversion);
|
296
|
-
return pixelsFromStart;
|
297
|
-
}
|
298
|
-
|
299
|
-
#oldPositionOfTime(time) {
|
300
|
-
let positionInDuration = (time - this.startTime) / (this.endTime - this.startTime + 1000);
|
301
|
-
let positionInCanvas = (positionInDuration * this.scrollHeight)
|
302
|
-
return positionInCanvas;
|
303
|
-
}
|
304
|
-
|
305
|
-
/////////////////////////////////////////
|
306
|
-
// Event Methods //
|
307
|
-
// (eventually switch to use template) //
|
308
|
-
/////////////////////////////////////////
|
309
|
-
|
310
|
-
#createEventDiv(startTime, endTime){
|
311
|
-
const eventDiv = document.createElement("div");
|
312
|
-
|
313
|
-
eventDiv.classList.add("event");
|
314
|
-
eventDiv.setAttribute("data-time-table-target", "event");
|
315
|
-
eventDiv.setAttribute("data-action", "mousedown->time-table#startDragEvent");
|
316
|
-
eventDiv.setAttribute("data-time-table-drag-event-param", "move");
|
317
|
-
|
318
|
-
eventDiv.innerHTML = `
|
319
|
-
<div class="event-name"><span style="font-weight: 400; color: gray;">(No Title)</span></div>
|
320
|
-
<div class="event-time" data-action="mousedown->time-table#startDragEvent" data-time-table-drag-event-param="resize">
|
321
|
-
${ this.#durationString(startTime, endTime) }
|
322
|
-
</div>
|
323
|
-
`;
|
324
|
-
|
325
|
-
this.#updateEventDiv(eventDiv, startTime, endTime);
|
326
|
-
this.eventsListTarget.appendChild(eventDiv);
|
327
|
-
|
328
|
-
return eventDiv;
|
329
|
-
}
|
330
|
-
|
331
|
-
#updateEventDiv(target, startTime, endTime) {
|
332
|
-
let startLocation = this.#positionOfTime(startTime);
|
333
|
-
let endLocation = this.#positionOfTime(endTime);
|
334
|
-
|
335
|
-
target.style.setProperty("top", `${startLocation}px`);
|
336
|
-
target.style.setProperty("height", `${endLocation - startLocation}px`);
|
337
|
-
|
338
|
-
this.#setSpecialClasses(target);
|
339
|
-
|
340
|
-
target.querySelector(".event-time").innerHTML = this.#durationString(startTime, endTime);
|
341
|
-
}
|
342
|
-
|
343
|
-
#setSpecialClasses(eventDiv) {
|
344
|
-
eventDiv.classList.toggle("tiny", eventDiv.offsetHeight < 15);
|
345
|
-
eventDiv.classList.toggle("small", eventDiv.offsetHeight < 45);
|
346
|
-
}
|
347
|
-
|
348
|
-
/////////////////////
|
349
|
-
// Time Formatters //
|
350
|
-
/////////////////////
|
351
|
-
|
352
|
-
#timeString(date, format = "long") {
|
353
|
-
let hours = date.getUTCHours();
|
354
|
-
let minutes = date.getUTCMinutes();
|
355
|
-
let ampm = hours >= 12 ? 'PM' : 'AM';
|
356
|
-
hours = hours % 12;
|
357
|
-
hours = hours ? hours : 12; // the hour '0' should be '12'
|
358
|
-
|
359
|
-
minutes = minutes < 10 ? '0' + minutes : minutes;
|
360
|
-
if(format == "long") {
|
361
|
-
return hours + ':' + minutes + ' ' + ampm;
|
362
|
-
} else if (format == "short") {
|
363
|
-
return hours + ampm
|
364
|
-
}
|
365
|
-
}
|
366
|
-
|
367
|
-
#durationString(startTime, endTime) {
|
368
|
-
return `${this.#timeString(startTime)} - ${this.#timeString(endTime)}`;
|
369
175
|
}
|
370
176
|
|
371
177
|
////////////////
|
@@ -374,7 +180,7 @@ export default class extends Controller {
|
|
374
180
|
|
375
181
|
#invokeDragMethodFor(type) {
|
376
182
|
if(!type) {
|
377
|
-
|
183
|
+
console.error("No drag type provided");
|
378
184
|
return;
|
379
185
|
}
|
380
186
|
let capitalizedType = type.charAt(0).toUpperCase() + type.slice(1);
|
@@ -390,27 +196,6 @@ export default class extends Controller {
|
|
390
196
|
// Helpers //
|
391
197
|
/////////////
|
392
198
|
|
393
|
-
static SCALE_RANGES = [
|
394
|
-
{ max: 40, clipSize: 60 },
|
395
|
-
{ max: 50, clipSize: 30 },
|
396
|
-
{ max: 150, clipSize: 15 },
|
397
|
-
{ max: 280, clipSize: 5 },
|
398
|
-
{ max: Infinity, clipSize: 1}
|
399
|
-
]
|
400
|
-
|
401
|
-
setClipSize(scale) {
|
402
|
-
this.clipSize = this.constructor.SCALE_RANGES.find(range => scale < range.max)?.clipSize || 15;
|
403
|
-
}
|
404
|
-
|
405
|
-
#setDragEventTarget(target) {
|
406
|
-
if(target) {
|
407
|
-
this.dragEvent.target = target;
|
408
|
-
this.dragEvent.originEventPosition = this.#relativeElementPosition(target);
|
409
|
-
this.dragEvent.originEventStartTime = this.#timeAtPosition(this.dragEvent.originEventPosition.y);
|
410
|
-
this.dragEvent.originEventEndTime = this.#timeAtPosition(this.dragEvent.originEventPosition.y + target.offsetHeight);
|
411
|
-
}
|
412
|
-
}
|
413
|
-
|
414
199
|
#setDragEventListeners() {
|
415
200
|
document.addEventListener("mousemove", this.drag.bind(this));
|
416
201
|
document.addEventListener("mouseup", this.stopDragEvent.bind(this));
|
@@ -422,148 +207,4 @@ export default class extends Controller {
|
|
422
207
|
document.removeEventListener("mouseup", this.stopDragEvent.bind(this));
|
423
208
|
document.removeEventListener("mouseleave", this.stopDragEvent.bind(this));
|
424
209
|
}
|
425
|
-
}
|
426
|
-
|
427
|
-
// this.dragEvent = new DragEvent();
|
428
|
-
// this.scrollFrame = new ScrollFrame(this.element);
|
429
|
-
|
430
|
-
|
431
|
-
// class DragHandler {
|
432
|
-
// constructor() {
|
433
|
-
// this.dragging = false;
|
434
|
-
// this.dragEvent = {};
|
435
|
-
// }
|
436
|
-
|
437
|
-
// startDrag(event) {
|
438
|
-
// event.preventDefault();
|
439
|
-
// event.stopPropagation();
|
440
|
-
|
441
|
-
// this.dragging = true;
|
442
|
-
// this.dragEvent.reset();
|
443
|
-
// this.dragEvent.type = event.params.dragEvent;
|
444
|
-
// }
|
445
|
-
|
446
|
-
// stopDrag(event) {
|
447
|
-
// event.preventDefault();
|
448
|
-
// this.dragging = false;
|
449
|
-
// this.dragEvent = {};
|
450
|
-
// }
|
451
|
-
|
452
|
-
// }
|
453
|
-
|
454
|
-
|
455
|
-
// this.scrollFrame = new ScrollFrame(this.element);
|
456
|
-
// this.scrollFrame.startBoundary = 0;
|
457
|
-
|
458
|
-
// Major Purpose - Calculate position of of a coordinate on screen and convert it to position relative to frame and scroll of element.
|
459
|
-
class ScrollFrame {
|
460
|
-
constructor(element, { origin = 0 }) {
|
461
|
-
this.element = element;
|
462
|
-
this.updateFrame();
|
463
|
-
this.origin = origin;
|
464
|
-
// this.endBoundary = this.element.scrollHeight;
|
465
|
-
}
|
466
|
-
|
467
|
-
get frame() {
|
468
|
-
return this.element.getBoundingClientRect();
|
469
|
-
}
|
470
|
-
|
471
|
-
updateFrame() {
|
472
|
-
// console.log("Updating frame");
|
473
|
-
this.frame = this.element.getBoundingClientRect();
|
474
|
-
}
|
475
|
-
|
476
|
-
relativeCursorPosition(event) {
|
477
|
-
return this.relativePosition(event.clientX, event.clientY);
|
478
|
-
}
|
479
|
-
|
480
|
-
relativePosition(x, y) {
|
481
|
-
return {
|
482
|
-
x: this.relativeXPosition(x),
|
483
|
-
y: this.relativeYPosition(y)
|
484
|
-
}
|
485
|
-
}
|
486
|
-
|
487
|
-
relativeScrollPosition(x, y) {
|
488
|
-
return {
|
489
|
-
x: this.relativeXScrollPosition(x),
|
490
|
-
y: this.relativeYScrollPosition(y)
|
491
|
-
}
|
492
|
-
}
|
493
|
-
|
494
|
-
relativeFramePosition(x, y) {
|
495
|
-
return {
|
496
|
-
x: this.relativeXFramePosition(x),
|
497
|
-
y: this.relativeYFramePosition(y)
|
498
|
-
}
|
499
|
-
}
|
500
|
-
|
501
|
-
relativeYPosition(y) {
|
502
|
-
return {
|
503
|
-
inFrame: this.relativeYFramePosition(y),
|
504
|
-
inScroll: this.relativeYScrollPosition(y)
|
505
|
-
}
|
506
|
-
}
|
507
|
-
|
508
|
-
relativeXPosition(x) {
|
509
|
-
return {
|
510
|
-
inFrame: this.relativeXFramePosition(x),
|
511
|
-
inScroll: this.relativeXScrollPosition(x)
|
512
|
-
}
|
513
|
-
}
|
514
|
-
|
515
|
-
relativeYFramePosition(y) {
|
516
|
-
return y - this.frame.top;
|
517
|
-
}
|
518
|
-
|
519
|
-
relativeYScrollPosition(y) {
|
520
|
-
return (this.relativeYFramePosition(y) - this.origin) + this.element.scrollTop;
|
521
|
-
}
|
522
|
-
|
523
|
-
relativeXFramePosition(x) {
|
524
|
-
return x - this.frame.left;
|
525
|
-
}
|
526
|
-
|
527
|
-
relativeXScrollPosition(x) {
|
528
|
-
return this.relativeXFramePosition(x) + this.element.scrollLeft;
|
529
|
-
}
|
530
|
-
|
531
|
-
#relativeYPosition(y) {
|
532
|
-
// return {
|
533
|
-
// frame:
|
534
|
-
// }
|
535
|
-
}
|
536
|
-
|
537
|
-
#relativePosition(x, y) {
|
538
|
-
// return
|
539
|
-
}
|
540
|
-
|
541
|
-
|
542
|
-
#relativeCursorPosition(event) {
|
543
|
-
this.updateFrame();
|
544
|
-
return {
|
545
|
-
x: event.clientX - this.dragEvent.frame.left,
|
546
|
-
y: (event.clientY - this.dragEvent.frame.top - 20) + this.element.scrollTop
|
547
|
-
};
|
548
|
-
}
|
549
|
-
|
550
|
-
#relativeElementPosition(element) {
|
551
|
-
this.updateFrame();
|
552
|
-
let rect = element.getBoundingClientRect();
|
553
|
-
return {
|
554
|
-
x: rect.left - this.dragEvent.frame.left,
|
555
|
-
y: (rect.top - this.dragEvent.frame.top - 20) + this.element.scrollTop
|
556
|
-
};
|
557
|
-
}
|
558
|
-
}
|
559
|
-
|
560
|
-
// relativePosition = {
|
561
|
-
// frame: {
|
562
|
-
// x: event.clientX - this.dragEvent.frame.left,
|
563
|
-
// y: (event.clientY - this.dragEvent.frame.top - 20) + this.element.scrollTop
|
564
|
-
// },
|
565
|
-
// scroll: {
|
566
|
-
// x: event.clientX - this.dragEvent.frame.left,
|
567
|
-
// y: (event.clientY - this.dragEvent.frame.top - 20) + this.element.scrollTop
|
568
|
-
// }
|
569
|
-
// }
|
210
|
+
}
|