Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timeline calendar num of days issues #2080

Merged
merged 12 commits into from
Nov 28, 2022
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 24 additions & 1 deletion src/dateutils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,30 @@ export function sameDate(a?: XDate, b?: XDate) {
return false;
} else {
return a?.getFullYear() === b?.getFullYear() && a?.getMonth() === b?.getMonth() && a?.getDate() === b?.getDate();
}
}
}

export function onSameDAteRange({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "A" on Date is capitalized... typo I guess

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

firstDay,
secondDay,
numberOfDays,
firstDateInRange,
}: {
firstDay: string;
secondDay: string;
numberOfDays: number;
firstDateInRange: string;
}){
const aDate = new XDate(firstDay);
const bDate = new XDate(secondDay);
const firstDayDate = new XDate(firstDateInRange);
const aDiff = aDate.getTime() - firstDayDate.getTime();
const bDiff = bDate.getTime() - firstDayDate.getTime();
const aTotalDays = Math.ceil(aDiff / (1000 * 3600 * 24));
const bTotalDays = Math.ceil(bDiff / (1000 * 3600 * 24));
const aWeek = Math.floor(aTotalDays / numberOfDays);
const bWeek = Math.floor(bTotalDays / numberOfDays);
return aWeek === bWeek;
}

export function sameWeek(a: string, b: string, firstDayOfWeek: number) {
Expand Down
4 changes: 2 additions & 2 deletions src/day-state-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ const {isToday, isDateNotInRange, sameMonth} = require('./dateutils');
const {toMarkingFormat} = require('./interface');


export function getState(day: XDate, current: XDate, props: any) {
export function getState(day: XDate, current: XDate, props: any, disableDaySelection?: boolean) {
const {minDate, maxDate, disabledByDefault, context} = props;
let state = '';

if ((context?.date ?? toMarkingFormat(current)) === toMarkingFormat(day)) {
if (!disableDaySelection && ((context?.date ?? toMarkingFormat(current)) === toMarkingFormat(day))) {
state = 'selected';
} else if (isToday(day)) {
state = 'today';
Expand Down
37 changes: 33 additions & 4 deletions src/expandableCalendar/WeekCalendar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import XDate from 'xdate';
import React, {useCallback, useContext, useMemo, useRef, useState} from 'react';
import {FlatList, View, ViewToken} from 'react-native';

import {sameWeek} from '../../dateutils';
import {sameWeek, onSameDAteRange} from '../../dateutils';
import {toMarkingFormat} from '../../interface';
import {DateData} from '../../types';
import styleConstructor from '../style';
Expand Down Expand Up @@ -36,7 +36,7 @@ const WeekCalendar = (props: WeekCalendarProps) => {
hideDayNames,
current,
theme,
testID
testID,
} = props;
const context = useContext(CalendarContext);
const {allowShadow = true, ...calendarListProps} = props;
Expand All @@ -50,9 +50,23 @@ const WeekCalendar = (props: WeekCalendarProps) => {
const list = useRef<FlatList>(null);
const currentIndex = useRef(NUMBER_OF_PAGES);

useDidUpdate(() => {
items.current = getDatesArray(date, firstDay, numberOfDays);
setListData(items.current);
visibleWeek.current = date;
}, [numberOfDays]);

useDidUpdate(() => {
if (updateSource !== UpdateSources.WEEK_SCROLL) {
const pageIndex = items.current.findIndex(item => sameWeek(item, date, firstDay));
const pageIndex = items.current.findIndex(
item => isCustomNumberOfDays(numberOfDays) ?
onSameDAteRange({
firstDay: item,
secondDay: date,
numberOfDays: numberOfDays as number,
firstDateInRange: item
}) :
sameWeek(item, date, firstDay));
if (pageIndex !== currentIndex.current) {
if (pageIndex >= 0) {
visibleWeek.current = items.current[pageIndex];
Expand Down Expand Up @@ -206,6 +220,14 @@ const WeekCalendar = (props: WeekCalendarProps) => {
);
};

function getDateForDayRange(date: string, weekIndex: number, numberOfDays: number) {
const d = new XDate(date);
if (weekIndex !== 0) {
d.addDays(numberOfDays * weekIndex);
}
return toMarkingFormat(d);
}

function getDate(date: string, firstDay: number, weekIndex: number, numberOfDays?: number) {
const d = new XDate(date);
// get the first day of the week as date (for the on scroll mark)
Expand All @@ -225,10 +247,17 @@ function getDate(date: string, firstDay: number, weekIndex: number, numberOfDays

function getDatesArray(date: string, firstDay: number, numberOfDays?: number) {
return [...Array(NUM_OF_ITEMS).keys()].map((index) => {
return getDate(date, firstDay, index - NUMBER_OF_PAGES, numberOfDays);
if(isCustomNumberOfDays(numberOfDays)) {
return getDateForDayRange(date, index - NUMBER_OF_PAGES, numberOfDays as number);
}
return getDate(date, firstDay, index - NUMBER_OF_PAGES);
});
}

function isCustomNumberOfDays(numberOfDays?: number) {
return numberOfDays && numberOfDays > 1;
}

WeekCalendar.displayName = 'WeekCalendar';

export default WeekCalendar;
41 changes: 23 additions & 18 deletions src/expandableCalendar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ enum Positions {
}
const SPEED = 20;
const BOUNCINESS = 6;
const CLOSED_HEIGHT = constants.isIOS ? 116 : 120; // header + 1 week
const CLOSED_HEIGHT = 120; // header + 1 week
const WEEK_HEIGHT = 46;
const DAY_NAMES_PADDING = 24;
const PAN_GESTURE_THRESHOLD = 30;
Expand Down Expand Up @@ -174,12 +174,17 @@ const ExpandableCalendar = (props: ExpandableCalendarProps) => {
return CLOSED_HEIGHT + (WEEK_HEIGHT * (numberOfWeeks.current - 1)) + (hideKnob ? 12 : KNOB_CONTAINER_HEIGHT) + (constants.isAndroid ? 3 : 0);
};
const openHeight = useRef(getOpenHeight());
const closedHeight = useRef(CLOSED_HEIGHT + (hideKnob || Number(numberOfDays) > 1 ? 0 : KNOB_CONTAINER_HEIGHT));
const closedHeight = useMemo(() => CLOSED_HEIGHT + (hideKnob || Number(numberOfDays) > 1 ? 0 : KNOB_CONTAINER_HEIGHT), [numberOfDays, hideKnob]);

const startHeight = isOpen ? openHeight.current : closedHeight.current;
const startHeight = useMemo(() => isOpen ? openHeight.current : closedHeight, [closedHeight, isOpen]);
const _height = useRef(startHeight);
const deltaY = useMemo(() => new Animated.Value(startHeight), [startHeight]);

useEffect(() => {
_height.current = startHeight;
deltaY.setValue(startHeight);
}, [startHeight]);

const deltaY = useRef(new Animated.Value(startHeight));
const headerDeltaY = useRef(new Animated.Value(isOpen ? -HEADER_HEIGHT : 0));

/** Components' refs */
Expand Down Expand Up @@ -221,7 +226,7 @@ const ExpandableCalendar = (props: ExpandableCalendarProps) => {
paddingRight: isNumber(rightPaddings) ? rightPaddings + 6 : DAY_NAMES_PADDING
}
];
}, [calendarStyle, numberOfDays]);
Inbal-Tish marked this conversation as resolved.
Show resolved Hide resolved
}, [calendarStyle]);

const animatedHeaderStyle = useMemo(() => {
return [style.current.header, {height: HEADER_HEIGHT + 10, top: headerDeltaY.current}];
Expand All @@ -236,8 +241,8 @@ const ExpandableCalendar = (props: ExpandableCalendarProps) => {
}, [allowShadow, propsStyle]);

const wrapperStyle = useMemo(() => {
return {height: deltaY.current};
}, [deltaY.current]);
return {height: deltaY};
}, [deltaY]);

/** Effects */

Expand Down Expand Up @@ -319,7 +324,7 @@ const ExpandableCalendar = (props: ExpandableCalendarProps) => {

const handlePanResponderMove = (_: GestureResponderEvent, gestureState: PanResponderGestureState) => {
// limit min height to closed height
_wrapperStyles.current.style.height = Math.max(closedHeight.current, _height.current + gestureState.dy);
_wrapperStyles.current.style.height = Math.max(closedHeight, _height.current + gestureState.dy);

if (!horizontal) {
// vertical CalenderList header
Expand Down Expand Up @@ -354,15 +359,15 @@ const ExpandableCalendar = (props: ExpandableCalendarProps) => {

const bounceToPosition = (toValue = 0) => {
if (!disablePan) {
const threshold = isOpen ? openHeight.current - closeThreshold : closedHeight.current + openThreshold;
const threshold = isOpen ? openHeight.current - closeThreshold : closedHeight + openThreshold;
let _isOpen = _height.current >= threshold;
const newValue = _isOpen ? openHeight.current : closedHeight.current;
const newValue = _isOpen ? openHeight.current : closedHeight;

deltaY.current.setValue(_height.current); // set the start position for the animated value
deltaY.setValue(_height.current); // set the start position for the animated value
_height.current = toValue || newValue;
_isOpen = _height.current >= threshold; // re-check after _height.current was set

Animated.spring(deltaY.current, {
Animated.spring(deltaY, {
toValue: _height.current,
speed: SPEED,
bounciness: BOUNCINESS,
Expand All @@ -371,7 +376,7 @@ const ExpandableCalendar = (props: ExpandableCalendarProps) => {

onCalendarToggled?.(_isOpen);

setPosition(() => _height.current === closedHeight.current ? Positions.CLOSED : Positions.OPEN);
setPosition(() => _height.current === closedHeight ? Positions.CLOSED : Positions.OPEN);
closeHeader(_isOpen);
resetWeekCalendarOpacity(_isOpen);
}
Expand Down Expand Up @@ -399,14 +404,14 @@ const ExpandableCalendar = (props: ExpandableCalendarProps) => {
setTimeout(() => {
// to allows setDate to be completed
if (isOpen) {
bounceToPosition(closedHeight.current);
bounceToPosition(closedHeight);
}
}, 0);
}, [isOpen]);
}, [isOpen, closedHeight]);

const toggleCalendarPosition = useCallback(() => {
bounceToPosition(isOpen ? closedHeight.current : openHeight.current);
}, [isOpen, bounceToPosition]);
bounceToPosition(isOpen ? closedHeight : openHeight.current);
}, [isOpen, bounceToPosition, closedHeight]);

/** Events */

Expand Down Expand Up @@ -552,7 +557,7 @@ const ExpandableCalendar = (props: ExpandableCalendarProps) => {

const _headerStyle = useMemo(() => {
return [numberOfDaysHeaderStyle, props.headerStyle];
}, [props.headerStyle]);
}, [props.headerStyle, numberOfDaysHeaderStyle]);

const renderCalendarList = () => {
return (
Expand Down
9 changes: 6 additions & 3 deletions src/expandableCalendar/week.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ const Week = React.memo((props: WeekProps) => {
} = props;
const style = useRef(styleConstructor(theme));

const disableDaySelection = useMemo(() => {
return !!numberOfDays && numberOfDays > 1;
}, [numberOfDays]);

const getWeek = useCallback((date?: string) => {
if (date) {
return getWeekDates(date, firstDay);
Expand All @@ -60,15 +64,14 @@ const Week = React.memo((props: WeekProps) => {
}
}
const dayString = toMarkingFormat(day);

return (
<View style={style.current.dayContainer} key={id}>
<Day
{...dayProps}
testID={`${testID}.day_${dayString}`}
date={dayString}
state={getState(day, currXdate, props)}
marking={markedDates?.[dayString]}
state={getState(day, currXdate, props, disableDaySelection)}
marking={disableDaySelection ? {...markedDates?.[dayString], disableTouchEvent: true} : markedDates?.[dayString]}
onPress={onDayPress}
onLongPress={onDayLongPress}
/>
Expand Down
27 changes: 15 additions & 12 deletions src/timeline-list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,24 @@ const TimelineList = (props: TimelineListProps) => {
const {pages, pagesRef, resetPages, resetPagesDebounce, scrollToPageDebounce, shouldResetPages, isOutOfRange} =
useTimelinePages({date, listRef, numberOfDays});

useEffect(() => {
if (date !== prevDate.current) {
const datePageIndex = pagesRef.current.indexOf(date);

if (updateSource !== UpdateSources.LIST_DRAG) {
if (isOutOfRange(datePageIndex)) {
updateSource === UpdateSources.DAY_PRESS ? resetPages(date) : resetPagesDebounce(date);
} else {
scrollToPageDebounce(datePageIndex);
}
const scrollToCurrentDate = useCallback((date: string) => {
const datePageIndex = pagesRef.current.indexOf(date);

if (updateSource !== UpdateSources.LIST_DRAG) {
if (isOutOfRange(datePageIndex)) {
updateSource === UpdateSources.DAY_PRESS ? resetPages(date) : resetPagesDebounce(date);
} else {
scrollToPageDebounce(datePageIndex);
}
}
prevDate.current = date;
}, [updateSource]);

prevDate.current = date;
useEffect(() => {
if (date !== prevDate.current) {
scrollToCurrentDate(date);
}
}, [date, updateSource]);
}, [date]);

const onScroll = useCallback(() => {
if (shouldResetPages.current) {
Expand Down
7 changes: 5 additions & 2 deletions src/timeline-list/useTimelinePages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@ const UseTimelinePages = ({date, listRef, numberOfDays}: UseTimelinePagesProps)
return generateDay(date, numberOfDays * (i - Math.floor(PAGES_COUNT / 2)));
})
);

const [pages, setPages] = useState<string[]>(pagesRef.current);
const shouldResetPages = useRef(false);

useEffect(() => {
setPages(times(PAGES_COUNT, i => {
const updatedDays = times(PAGES_COUNT, i => {
return generateDay(date, numberOfDays * (i - Math.floor(PAGES_COUNT / 2)));
}));
});
pagesRef.current = updatedDays;
setPages(updatedDays);
}, [numberOfDays]);

const isOutOfRange = useCallback((index: number) => {
Expand Down