Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into hotfix/timezones
Browse files Browse the repository at this point in the history
  • Loading branch information
callaars committed Mar 2, 2023
2 parents 6eb7cb1 + e36f2f3 commit de4c321
Show file tree
Hide file tree
Showing 14 changed files with 129 additions and 50 deletions.
9 changes: 7 additions & 2 deletions documentation/docs/guides/other-props.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ Use calendar in different time zones

<span style={{color: "grey"}}>string</span>


### renderHalfLineCustom

Custom component rendered inside the line in the middle of the interval
Expand All @@ -205,4 +204,10 @@ Container style of the line in the middle of the interval.

Update indicator at specified intervals (in milliseconds). Default is `1000`

<span style={{color: "grey"}}>number</span>
<span style={{color: "grey"}}>number</span>

### calendarWidth

Width of calendar. Default is `window width`

<span style={{color: "grey"}}>number</span>
4 changes: 2 additions & 2 deletions documentation/docs/guides/view-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ sidebar_position: 1
TimelineCalendar has 4 modes: **week**, **day**, **threeDays** and **workWeek**

```jsx title="Example"
import { SafeAreaView, Text } from 'react-native';
import React from 'react';
import { SafeAreaView, StyleSheet } from 'react-native';
import { TimelineCalendar } from '@howljs/calendar-kit';

const Calendar = () => {
Expand All @@ -20,7 +20,7 @@ const Calendar = () => {

export default Calendar;

const style = StyleSheet.create({
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#FFF' },
});
```
Expand Down
28 changes: 27 additions & 1 deletion example/src/screens/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,19 @@ import type { NavigationProp, RouteProp } from '@react-navigation/native';
import dayjs from 'dayjs';
import React, {
useCallback,
useEffect,
useLayoutEffect,
useMemo,
useRef,
useState,
} from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import {
AppState,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { Line, Svg } from 'react-native-svg';
import CustomUnavailableItem from './CustomUnavailableItem';
Expand Down Expand Up @@ -89,6 +96,25 @@ const Calendar = ({ route, navigation }: CalendarProps) => {
const [events, setEvents] = useState<EventItem[]>([]);
const [selectedEvent, setSelectedEvent] = useState<PackedEvent>();

const appState = useRef(AppState.currentState);
// if autoRefreshTimezoneOffset = true, you can remove this useEffect
useEffect(() => {
const subscription = AppState.addEventListener('change', (nextAppState) => {
if (
appState.current.match(/inactive|background/) &&
nextAppState === 'active'
) {
// Recheck timezone offset the app has come to the foreground
calendarRef.current?.recheckTimezoneOffset();
}
appState.current = nextAppState;
});

return () => {
subscription.remove();
};
}, []);

const _renderHeaderRight = useCallback(() => {
return (
<TouchableOpacity
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@howljs/calendar-kit",
"version": "1.11.0",
"version": "1.12.0",
"description": "React Native Calendar Kit",
"main": "lib/commonjs/index",
"module": "lib/module/index",
Expand Down
39 changes: 19 additions & 20 deletions src/components/Timeline/DragEditItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ const DragEditItem = ({
rightEdgeSpacing,
]);

const timeoutRef = useSharedValue<NodeJS.Timeout | null>(null);
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
const _handleScroll = ({
x,
y,
Expand All @@ -111,23 +111,23 @@ const DragEditItem = ({
y: number;
type: 'swipe_down' | 'swipe_up';
}) => {
if (timeoutRef.value && x > hourWidth && x < timelineWidth - 25) {
clearInterval(timeoutRef.value);
timeoutRef.value = null;
if (timeoutRef.current && x > hourWidth && x < timelineWidth - 25) {
clearInterval(timeoutRef.current);
timeoutRef.current = null;
}
if (x <= hourWidth) {
if (isScrolling.current || timeoutRef.value) {
if (isScrolling.current || timeoutRef.current) {
return;
}
timeoutRef.value = setInterval(() => {
timeoutRef.current = setInterval(() => {
goToPrevPage(true);
}, navigateDelay);
}
if (x >= timelineWidth - 25) {
if (isScrolling.current || timeoutRef.value) {
if (isScrolling.current || timeoutRef.current) {
return;
}
timeoutRef.value = setInterval(() => {
timeoutRef.current = setInterval(() => {
goToNextPage(true);
}, navigateDelay);
}
Expand Down Expand Up @@ -187,9 +187,9 @@ const DragEditItem = ({
};

const clearCurrentInterval = () => {
if (timeoutRef.value) {
clearInterval(timeoutRef.value);
timeoutRef.value = null;
if (timeoutRef.current) {
clearInterval(timeoutRef.current);
timeoutRef.current = null;
}
};

Expand Down Expand Up @@ -232,10 +232,7 @@ const DragEditItem = ({
duration: 100,
easing: Easing.linear,
});
eventTop.value = withTiming(newTopPosition, {
duration: 100,
easing: Easing.linear,
});
eventTop.value = newTopPosition;
currentHour.value = roundedHour + start;
if (useHaptic) {
runOnJS(triggerHaptic)();
Expand Down Expand Up @@ -272,10 +269,7 @@ const DragEditItem = ({
const clampedHeight = Math.max(roundedHeight, heightOfTenMinutes);
const isSameHeight = eventHeight.value === clampedHeight;
if (!isSameHeight) {
eventHeight.value = withTiming(clampedHeight, {
duration: 100,
easing: Easing.linear,
});
eventHeight.value = clampedHeight;
if (useHaptic) {
runOnJS(triggerHaptic)();
}
Expand Down Expand Up @@ -474,7 +468,12 @@ const styles = StyleSheet.create({
alignItems: 'center',
height: 24,
},
title: { paddingVertical: 4, paddingHorizontal: 2, fontSize: 10 },
title: {
paddingVertical: 4,
paddingHorizontal: 2,
fontSize: 10,
color: DEFAULT_PROPS.BLACK_COLOR,
},
hourText: {
color: DEFAULT_PROPS.PRIMARY_COLOR,
fontSize: 10,
Expand Down
8 changes: 7 additions & 1 deletion src/components/Timeline/EventBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Animated, {
useAnimatedStyle,
withTiming,
} from 'react-native-reanimated';
import { DEFAULT_PROPS } from '../../constants';
import type { PackedEvent, ThemeProperties } from '../../types';
import { shallowEqual } from '../../utils';

Expand Down Expand Up @@ -151,5 +152,10 @@ const styles = StyleSheet.create({
borderRadius: 4,
overflow: 'hidden',
},
title: { paddingVertical: 4, paddingHorizontal: 2, fontSize: 10 },
title: {
paddingVertical: 4,
paddingHorizontal: 2,
fontSize: 10,
color: DEFAULT_PROPS.BLACK_COLOR,
},
});
4 changes: 2 additions & 2 deletions src/components/Timeline/NowIndicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface NowIndicatorProps {
tzOffset: string;
start: number;
updateCurrentDate: () => void;
recheckTimezoneOffset: () => void;
recheckTimezoneOffset?: () => void;
nowIndicatorInterval: number;
}

Expand Down Expand Up @@ -44,7 +44,7 @@ const NowIndicator = ({

const prevMinutes = useRef(initial.current.minutes);
const updateLinePosition = useCallback(() => {
recheckTimezoneOffset();
recheckTimezoneOffset?.();
const { date, minutes } = getCurrentMinutes(tzOffset);
if (prevMinutes.current === minutes) {
return;
Expand Down
9 changes: 7 additions & 2 deletions src/components/Timeline/TimelineHours.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Animated, {
SharedValue,
useAnimatedStyle,
} from 'react-native-reanimated';
import { DEFAULT_PROPS } from '../../constants';
import { useTimelineCalendarContext } from '../../context/TimelineProvider';
import type { ThemeProperties } from '../../types';

Expand Down Expand Up @@ -83,10 +84,14 @@ const styles = StyleSheet.create({
alignItems: 'center',
overflow: 'hidden',
},
hourText: { position: 'absolute', fontSize: 10 },
hourText: {
position: 'absolute',
fontSize: 10,
color: DEFAULT_PROPS.BLACK_COLOR,
},
verticalLine: {
width: 1,
backgroundColor: '#E8E9ED',
backgroundColor: DEFAULT_PROPS.CELL_BORDER_COLOR,
position: 'absolute',
right: 0,
height: '100%',
Expand Down
5 changes: 4 additions & 1 deletion src/components/Timeline/TimelinePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ const TimelinePage = ({
nowIndicatorInterval,
isPinchActive,
recheckTimezoneOffset,
autoRefreshTimezoneOffset,
} = useTimelineCalendarContext();

const eventsByColumns = useMemo(
Expand Down Expand Up @@ -180,7 +181,9 @@ const TimelinePage = ({
tzOffset={tzOffset}
start={start}
updateCurrentDate={updateCurrentDate}
recheckTimezoneOffset={recheckTimezoneOffset}
recheckTimezoneOffset={
autoRefreshTimezoneOffset ? recheckTimezoneOffset : undefined
}
nowIndicatorInterval={nowIndicatorInterval}
/>
)}
Expand Down
21 changes: 21 additions & 0 deletions src/components/Timeline/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const Timeline: React.ForwardRefRenderFunction<
offsetY,
timelineVerticalListRef,
initialTimeIntervalHeight,
recheckTimezoneOffset,
} = useTimelineCalendarContext();
const { goToNextPage, goToPrevPage, goToOffsetY } = useTimelineScroll();

Expand Down Expand Up @@ -118,13 +119,31 @@ const Timeline: React.ForwardRefRenderFunction<
goToPrevPage: goToPrevPage,
getZones: () => Object.values(timeZoneData),
getZone: (key: keyof typeof timeZoneData) => timeZoneData[key],
getHour: () => {
const position = offsetY.value + 8;
const minutes =
((position - spaceFromTop) * 60) / timeIntervalHeight.value;
const hour = minutes / 60;
return Math.max(0, hour);
},
getDate: () => {
const numOfDays =
viewMode === 'workWeek' ? COLUMNS.week : COLUMNS[viewMode];
const firstDateMoment = dayjs(firstDate.current[viewMode]);
const pageIndex = currentIndex.value;
const currentDay = firstDateMoment
.add(pageIndex * numOfDays, 'd')
.add(tzOffset, 'm');
return currentDay.toISOString();
},
goToHour: (hour: number, animated?: boolean) => {
const minutes = hour * 60;
const position =
(minutes * timeIntervalHeight.value) / 60 + spaceFromTop;
goToOffsetY(Math.max(0, position - 8), animated);
},
forceUpdateNowIndicator: updateCurrentDate,
recheckTimezoneOffset: recheckTimezoneOffset,
zoom: (props?: { scale?: number; height?: number }) => {
let newHeight = props?.height ?? initialTimeIntervalHeight;
if (props?.scale) {
Expand Down Expand Up @@ -152,13 +171,15 @@ const Timeline: React.ForwardRefRenderFunction<
totalPages,
timelineHorizontalListRef,
timeIntervalHeight,
currentIndex.value,
spaceFromTop,
goToOffsetY,
minTimeIntervalHeight.value,
maxTimeIntervalHeight,
offsetY.value,
timelineVerticalListRef,
initialTimeIntervalHeight,
recheckTimezoneOffset,
]
);

Expand Down
9 changes: 8 additions & 1 deletion src/context/TimelineProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type CustomTimelineProviderProps = Required<
| 'unavailableHours'
| 'hourFormat'
| 'timeZone'
| 'calendarWidth'
>
>;

Expand Down Expand Up @@ -120,9 +121,13 @@ const TimelineProvider: React.FC<TimelineProviderProps> = (props) => {
timeZone = moment.tz.guess(),
nowIndicatorInterval = DEFAULT_PROPS.NOW_INDICATOR_INTERVAL,
navigateDelay = DEFAULT_PROPS.NAVIGATION_DELAY,
autoRefreshTimezoneOffset = false,
calendarWidth,
} = props;

const { width: timelineWidth } = useWindowDimensions();
const { width: windowWidth } = useWindowDimensions();

const timelineWidth = calendarWidth || windowWidth;

/** Refs */
const dayBarListRef = useRef<FlashList<string>>(null);
Expand Down Expand Up @@ -261,6 +266,7 @@ const TimelineProvider: React.FC<TimelineProviderProps> = (props) => {
numOfColumns,
recheckTimezoneOffset: () => {},
initialTimeIntervalHeight,
autoRefreshTimezoneOffset,
};
}, [
pages,
Expand Down Expand Up @@ -306,6 +312,7 @@ const TimelineProvider: React.FC<TimelineProviderProps> = (props) => {
isPinchActive,
navigateDelay,
initialTimeIntervalHeight,
autoRefreshTimezoneOffset,
]);

const mountedRef = useRef(false);
Expand Down
Loading

0 comments on commit de4c321

Please sign in to comment.