@sunsama/event-calendar 0.11.0 → 0.11.2
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.
- package/lib/commonjs/components/background-hours-content.js +12 -4
- package/lib/commonjs/components/background-hours-content.js.map +1 -1
- package/lib/commonjs/components/background-hours-layout.js +17 -9
- package/lib/commonjs/components/background-hours-layout.js.map +1 -1
- package/lib/commonjs/components/timed-events.js +2 -0
- package/lib/commonjs/components/timed-events.js.map +1 -1
- package/lib/commonjs/components/zoom-provider.js +6 -74
- package/lib/commonjs/components/zoom-provider.js.map +1 -1
- package/lib/commonjs/hooks/use-long-press-new-event.js +83 -0
- package/lib/commonjs/hooks/use-long-press-new-event.js.map +1 -0
- package/lib/commonjs/index.js +0 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/components/background-hours-content.js +12 -5
- package/lib/module/components/background-hours-content.js.map +1 -1
- package/lib/module/components/background-hours-layout.js +16 -9
- package/lib/module/components/background-hours-layout.js.map +1 -1
- package/lib/module/components/timed-events.js +2 -0
- package/lib/module/components/timed-events.js.map +1 -1
- package/lib/module/components/zoom-provider.js +7 -75
- package/lib/module/components/zoom-provider.js.map +1 -1
- package/lib/module/hooks/use-long-press-new-event.js +79 -0
- package/lib/module/hooks/use-long-press-new-event.js.map +1 -0
- package/lib/module/index.js +0 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/commonjs/components/background-hours-content.d.ts +3 -1
- package/lib/typescript/commonjs/components/background-hours-content.d.ts.map +1 -1
- package/lib/typescript/commonjs/components/background-hours-layout.d.ts +3 -1
- package/lib/typescript/commonjs/components/background-hours-layout.d.ts.map +1 -1
- package/lib/typescript/commonjs/components/zoom-provider.d.ts +2 -2
- package/lib/typescript/commonjs/components/zoom-provider.d.ts.map +1 -1
- package/lib/typescript/commonjs/hooks/use-long-press-new-event.d.ts +3 -0
- package/lib/typescript/commonjs/hooks/use-long-press-new-event.d.ts.map +1 -0
- package/lib/typescript/module/components/background-hours-content.d.ts +3 -1
- package/lib/typescript/module/components/background-hours-content.d.ts.map +1 -1
- package/lib/typescript/module/components/background-hours-layout.d.ts +3 -1
- package/lib/typescript/module/components/background-hours-layout.d.ts.map +1 -1
- package/lib/typescript/module/components/zoom-provider.d.ts +2 -2
- package/lib/typescript/module/components/zoom-provider.d.ts.map +1 -1
- package/lib/typescript/module/hooks/use-long-press-new-event.d.ts +3 -0
- package/lib/typescript/module/hooks/use-long-press-new-event.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/components/background-hours-content.tsx +24 -17
- package/src/components/background-hours-layout.tsx +25 -18
- package/src/components/timed-events.tsx +2 -2
- package/src/components/zoom-provider.tsx +54 -154
- package/src/hooks/use-long-press-new-event.ts +103 -0
- package/src/index.tsx +1 -1
|
@@ -4,10 +4,9 @@ import Animated, {
|
|
|
4
4
|
useSharedValue,
|
|
5
5
|
} from "react-native-reanimated";
|
|
6
6
|
import { Gesture, GestureDetector } from "react-native-gesture-handler";
|
|
7
|
-
import {
|
|
8
|
-
import { ConfigProvider
|
|
7
|
+
import { useContext, useEffect } from "react";
|
|
8
|
+
import { ConfigProvider } from "../utils/globals";
|
|
9
9
|
import { StyleSheet } from "react-native";
|
|
10
|
-
import { useIsEditing } from "../hooks/use-is-editing";
|
|
11
10
|
import doubleTapGesture from "../utils/double-tap-reset-zoom-gesture";
|
|
12
11
|
|
|
13
12
|
type ZoomProviderProps = {
|
|
@@ -17,160 +16,61 @@ type ZoomProviderProps = {
|
|
|
17
16
|
// This fraction determines how quickly zoom grows
|
|
18
17
|
const fraction = 0.1;
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
.enabled(canCreateEvents && !isEditing)
|
|
73
|
-
.withRef(refNewEvent as any)
|
|
74
|
-
.numberOfPointers(1)
|
|
75
|
-
.minDuration(250)
|
|
76
|
-
.maxDistance(10000)
|
|
77
|
-
.onStart((event) => {
|
|
78
|
-
"worklet";
|
|
79
|
-
|
|
80
|
-
isDragging.value = true;
|
|
81
|
-
createY.value = Math.max(
|
|
82
|
-
0,
|
|
83
|
-
event.y - TOP_MARGIN_PIXEL_OFFSET - (zoomLevel.value * 60) / 2
|
|
84
|
-
);
|
|
85
|
-
})
|
|
86
|
-
.onTouchesMove((event) => {
|
|
87
|
-
"worklet";
|
|
88
|
-
|
|
89
|
-
if (!isDragging.value) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (!fiveMinuteInterval) {
|
|
94
|
-
createY.value = Math.max(
|
|
95
|
-
0,
|
|
96
|
-
event.allTouches[0].y -
|
|
97
|
-
TOP_MARGIN_PIXEL_OFFSET -
|
|
98
|
-
(zoomLevel.value * 60) / 2
|
|
99
|
-
);
|
|
100
|
-
} else {
|
|
101
|
-
const normalizedY =
|
|
102
|
-
event.allTouches[0].y -
|
|
103
|
-
TOP_MARGIN_PIXEL_OFFSET -
|
|
104
|
-
(zoomLevel.value * 60) / 2;
|
|
105
|
-
const time = Math.floor(normalizedY / zoomLevel.value);
|
|
106
|
-
const hour = Math.floor(time / 60);
|
|
107
|
-
const minute = time - hour * 60;
|
|
108
|
-
const minuteInterval = Math.floor(minute / 5) * 5;
|
|
109
|
-
|
|
110
|
-
createY.value = (hour * 60 + minuteInterval) * zoomLevel.value;
|
|
111
|
-
}
|
|
112
|
-
})
|
|
113
|
-
.onEnd((event, success) => {
|
|
114
|
-
"worklet";
|
|
115
|
-
|
|
116
|
-
if (!isDragging.value) {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Make sure it doesn't show the new event component anymore
|
|
121
|
-
createY.value = -1;
|
|
122
|
-
yPosition.value = -1;
|
|
123
|
-
isDragging.value = false;
|
|
124
|
-
|
|
125
|
-
if (!success) {
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Determine the hour that was clicked and trigger the event creation
|
|
130
|
-
const normalizedY =
|
|
131
|
-
event.y - TOP_MARGIN_PIXEL_OFFSET - (zoomLevel.value * 60) / 2;
|
|
132
|
-
const time = Math.floor(normalizedY / zoomLevel.value);
|
|
133
|
-
const hour = Math.floor(time / 60);
|
|
134
|
-
const minute = time - hour * 60;
|
|
135
|
-
|
|
136
|
-
if (!onCreateEvent) {
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (fiveMinuteInterval) {
|
|
141
|
-
const minuteInterval = Math.floor(minute / 5) * 5;
|
|
142
|
-
|
|
143
|
-
runOnJS(onCreateEvent)({
|
|
144
|
-
hour,
|
|
145
|
-
minute: minuteInterval,
|
|
146
|
-
});
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
runOnJS(onCreateEvent)({
|
|
151
|
-
hour,
|
|
152
|
-
minute,
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
const combinedGesture = Gesture.Simultaneous(
|
|
157
|
-
pinchGesture,
|
|
158
|
-
longPressGesture,
|
|
159
|
-
doubleTapGesture(zoomLevel, defaultZoomLevel, onZoomChange)
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
return (
|
|
163
|
-
<GestureDetector gesture={combinedGesture}>
|
|
164
|
-
<Animated.View style={styles.container}>{children}</Animated.View>
|
|
165
|
-
</GestureDetector>
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
);
|
|
19
|
+
export default function ZoomProvider({ children }: ZoomProviderProps) {
|
|
20
|
+
const {
|
|
21
|
+
zoomLevel,
|
|
22
|
+
defaultZoomLevel,
|
|
23
|
+
maxZoomLevel,
|
|
24
|
+
minZoomLevel,
|
|
25
|
+
maximumHour,
|
|
26
|
+
onZoomChange,
|
|
27
|
+
} = useContext(ConfigProvider);
|
|
28
|
+
const previewScale = useSharedValue(-1);
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
previewScale.value = zoomLevel.get();
|
|
32
|
+
}, [zoomLevel, previewScale]);
|
|
33
|
+
|
|
34
|
+
const pinchGesture = Gesture.Pinch()
|
|
35
|
+
.onUpdate((event) => {
|
|
36
|
+
"worklet";
|
|
37
|
+
|
|
38
|
+
const newScale = previewScale.value * (1 + fraction * (event.scale - 1));
|
|
39
|
+
|
|
40
|
+
zoomLevel.value = Math.min(
|
|
41
|
+
maxZoomLevel,
|
|
42
|
+
Math.max(minZoomLevel, newScale)
|
|
43
|
+
);
|
|
44
|
+
previewScale.value = zoomLevel.value;
|
|
45
|
+
})
|
|
46
|
+
.onEnd(() => {
|
|
47
|
+
if (onZoomChange) {
|
|
48
|
+
runOnJS(onZoomChange)(zoomLevel.value);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
useAnimatedReaction(
|
|
53
|
+
() => zoomLevel.value,
|
|
54
|
+
(zoom) => {
|
|
55
|
+
maximumHour.value = 1440 * zoom;
|
|
56
|
+
},
|
|
57
|
+
[maximumHour]
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const combinedGesture = Gesture.Simultaneous(
|
|
61
|
+
pinchGesture,
|
|
62
|
+
doubleTapGesture(zoomLevel, defaultZoomLevel, onZoomChange)
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<GestureDetector gesture={combinedGesture}>
|
|
67
|
+
<Animated.View style={styles.container}>{children}</Animated.View>
|
|
68
|
+
</GestureDetector>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
169
71
|
|
|
170
72
|
const styles = StyleSheet.create({
|
|
171
73
|
container: {
|
|
172
74
|
flex: 1,
|
|
173
75
|
},
|
|
174
76
|
});
|
|
175
|
-
|
|
176
|
-
export default ZoomProvider;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Gesture } from "react-native-gesture-handler";
|
|
2
|
+
import { ConfigProvider, TOP_MARGIN_PIXEL_OFFSET } from "src/utils/globals";
|
|
3
|
+
import { runOnJS, useSharedValue } from "react-native-reanimated";
|
|
4
|
+
import { useIsEditing } from "src/hooks/use-is-editing";
|
|
5
|
+
import { type RefObject, useContext } from "react";
|
|
6
|
+
|
|
7
|
+
export default function useLongPressNewEvent(refNewEvent: RefObject<any>) {
|
|
8
|
+
const {
|
|
9
|
+
canCreateEvents,
|
|
10
|
+
zoomLevel,
|
|
11
|
+
createY,
|
|
12
|
+
onCreateEvent,
|
|
13
|
+
fiveMinuteInterval,
|
|
14
|
+
} = useContext(ConfigProvider);
|
|
15
|
+
const yPosition = useSharedValue(-1);
|
|
16
|
+
const { isEditing } = useIsEditing();
|
|
17
|
+
const isDragging = useSharedValue(false);
|
|
18
|
+
|
|
19
|
+
return Gesture.LongPress()
|
|
20
|
+
.enabled(canCreateEvents && !isEditing)
|
|
21
|
+
.withRef(refNewEvent as any)
|
|
22
|
+
.numberOfPointers(1)
|
|
23
|
+
.minDuration(250)
|
|
24
|
+
.maxDistance(10000)
|
|
25
|
+
.onStart((event) => {
|
|
26
|
+
"worklet";
|
|
27
|
+
|
|
28
|
+
isDragging.value = true;
|
|
29
|
+
createY.value = Math.max(
|
|
30
|
+
0,
|
|
31
|
+
event.y - TOP_MARGIN_PIXEL_OFFSET - (zoomLevel.value * 60) / 2
|
|
32
|
+
);
|
|
33
|
+
})
|
|
34
|
+
.onTouchesMove((event) => {
|
|
35
|
+
"worklet";
|
|
36
|
+
|
|
37
|
+
if (!isDragging.value) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!fiveMinuteInterval) {
|
|
42
|
+
createY.value = Math.max(
|
|
43
|
+
0,
|
|
44
|
+
event.allTouches[0].y -
|
|
45
|
+
TOP_MARGIN_PIXEL_OFFSET -
|
|
46
|
+
(zoomLevel.value * 60) / 2
|
|
47
|
+
);
|
|
48
|
+
} else {
|
|
49
|
+
const normalizedY =
|
|
50
|
+
event.allTouches[0].y -
|
|
51
|
+
TOP_MARGIN_PIXEL_OFFSET -
|
|
52
|
+
(zoomLevel.value * 60) / 2;
|
|
53
|
+
const time = Math.floor(normalizedY / zoomLevel.value);
|
|
54
|
+
const hour = Math.floor(time / 60);
|
|
55
|
+
const minute = time - hour * 60;
|
|
56
|
+
const minuteInterval = Math.floor(minute / 5) * 5;
|
|
57
|
+
|
|
58
|
+
createY.value = (hour * 60 + minuteInterval) * zoomLevel.value;
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
.onEnd((event, success) => {
|
|
62
|
+
"worklet";
|
|
63
|
+
|
|
64
|
+
if (!isDragging.value) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Make sure it doesn't show the new event component anymore
|
|
69
|
+
createY.value = -1;
|
|
70
|
+
yPosition.value = -1;
|
|
71
|
+
isDragging.value = false;
|
|
72
|
+
|
|
73
|
+
if (!success) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Determine the hour that was clicked and trigger the event creation
|
|
78
|
+
const normalizedY =
|
|
79
|
+
event.y - TOP_MARGIN_PIXEL_OFFSET - (zoomLevel.value * 60) / 2;
|
|
80
|
+
const time = Math.floor(normalizedY / zoomLevel.value);
|
|
81
|
+
const hour = Math.floor(time / 60);
|
|
82
|
+
const minute = time - hour * 60;
|
|
83
|
+
|
|
84
|
+
if (!onCreateEvent) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (fiveMinuteInterval) {
|
|
89
|
+
const minuteInterval = Math.floor(minute / 5) * 5;
|
|
90
|
+
|
|
91
|
+
runOnJS(onCreateEvent)({
|
|
92
|
+
hour,
|
|
93
|
+
minute: minuteInterval,
|
|
94
|
+
});
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
runOnJS(onCreateEvent)({
|
|
99
|
+
hour,
|
|
100
|
+
minute,
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}
|
package/src/index.tsx
CHANGED
|
@@ -225,7 +225,7 @@ function EventCalendarContentInner<T extends CalendarEvent>(
|
|
|
225
225
|
onScroll={onScrollFeedback}
|
|
226
226
|
>
|
|
227
227
|
<IsEditingProvider ref={refEditingProvider}>
|
|
228
|
-
<ZoomProvider
|
|
228
|
+
<ZoomProvider>
|
|
229
229
|
<View style={[styles.borderContainer, theme?.borderContainer]} />
|
|
230
230
|
<TimedEvents refNewEvent={refNewEvent} />
|
|
231
231
|
</ZoomProvider>
|