react-native-calendars
react-native-calendars copied to clipboard
TimelineList onEventPress, event is undefined
This is how i managed the code:
onEventPress = (event: TimelineEventProps) => {
console.log("TimelineCalendarScreen onEventPress: ", event);
};`
<TimelineList
events={eventsByDate}
timelineProps={this.timelineProps}
showNowIndicator
scrollToNow
scrollToFirst
initialTime={INITIAL_TIME}
/>
format24h: true,
onBackgroundLongPress: this.createNewEvent,
onBackgroundLongPressOut: this.approveNewEvent,
onEventPress: this.onEventPress,
unavailableHours: [
{ start: 0, end: 16.5 },
{ start: 20, end: 24 },
],
overlapEventsSpacing: 8,
rightEdgeSpacing: 24,
};
When i press the event in the calendar it logs undefined
Full code:
import { router } from "expo-router";
import filter from "lodash/filter";
import find from "lodash/find";
import groupBy from "lodash/groupBy";
import React, { Component } from "react";
import { Alert } from "react-native";
import {
ExpandableCalendar,
TimelineEventProps,
TimelineList,
CalendarProvider,
TimelineProps,
CalendarUtils,
} from "react-native-calendars";
import ScheduleRepository from "@/src/repositories/schedule";
import { showToast } from "@/src/services/message";
import useScheduleStore from "@/src/stores/schedule";
import useStore from "@/src/stores/store";
import Theme from "@/src/styles/theme";
import { convertFromISO, formatTimelineDate } from "@/src/utils/date";
export function getDate(offset = 0) {
const today = new Date();
const targetDate = new Date(today);
targetDate.setDate(today.getDate() + offset);
const year = targetDate.getFullYear();
const month = String(targetDate.getMonth() + 1).padStart(2, "0");
const day = String(targetDate.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}
export const timelineEvents = [
{
id: "1",
start: "2023-11-05T10:00:00",
end: "2023-11-05T12:00:00",
title: "Agendamento",
color: Theme.colors.grayLighter,
},
];
const INITIAL_TIME = { hour: 9, minutes: 0 };
const EVENTS: TimelineEventProps[] = timelineEvents;
export default class TimelineCalendarScreen extends Component {
state = {
currentDate: getDate(),
events: EVENTS,
eventsByDate: groupBy(EVENTS, (e) =>
CalendarUtils.getCalendarDateString(e.start),
) as {
[key: string]: TimelineEventProps[];
},
};
// marked = {
// [`${getDate(-1)}`]: { marked: true },
// [`${getDate()}`]: { marked: true },
// [`${getDate(1)}`]: { marked: true },
// [`${getDate(2)}`]: { marked: true },
// [`${getDate(4)}`]: { marked: true },
// };
marked = {};
async componentDidMount() {
useStore.getState().actions.setIsLoading(true);
await this.getServerEvents();
useStore.getState().actions.setIsLoading(false);
}
onDateChanged = (date: string, source: string) => {
console.log("TimelineCalendarScreen onDateChanged: ", date, source);
this.setState({ currentDate: date });
};
onMonthChange = (month: any, updateSource: any) => {
console.log("TimelineCalendarScreen onMonthChange: ", month, updateSource);
};
getServerEvents = async () => {
const { eventsByDate } = this.state;
try {
const schedules: models.Schedule[] = await ScheduleRepository.getAll();
const newEvents = schedules.map((schedule) => ({
id: schedule.id,
start: schedule.startAt,
end: schedule.endAt,
title: "Agendamento",
color: Theme.colors.grayLighter,
}));
const newEventsByDate = groupBy(newEvents, (e) =>
CalendarUtils.getCalendarDateString(e.start),
);
this.setState({
events: [...newEvents, ...EVENTS],
eventsByDate: { ...eventsByDate, ...newEventsByDate },
});
} catch (error) {
console.log(error);
}
};
onEventPress = (event: TimelineEventProps) => {
console.log("TimelineCalendarScreen onEventPress: ", event);
};
createNewEvent: TimelineProps["onBackgroundLongPress"] = (
timeString,
timeObject,
) => {
const { eventsByDate } = this.state;
const hourString = `${(timeObject.hour + 3).toString().padStart(2, "0")}`;
const minutesString = `${timeObject.minutes.toString().padStart(2, "0")}`;
const conflictsWithOtherEvents = this.state.events.some(
(event) =>
event.start === formatTimelineDate(timeString) ||
event.end === formatTimelineDate(timeString) ||
(event.start < formatTimelineDate(timeString) &&
event.end > formatTimelineDate(timeString)),
);
if (conflictsWithOtherEvents) {
showToast("Horário indisponível");
return;
}
const newEvent = {
id: "draft",
start: `${timeString}`,
end: `${timeObject.date} ${hourString}:${minutesString}:00`,
title: "Agendamento",
};
if (timeObject.date) {
if (eventsByDate[timeObject.date]) {
eventsByDate[timeObject.date] = [
...eventsByDate[timeObject.date],
newEvent,
];
this.setState({ eventsByDate });
} else {
eventsByDate[timeObject.date] = [newEvent];
this.setState({ eventsByDate: { ...eventsByDate } });
}
}
};
approveNewEvent: TimelineProps["onBackgroundLongPressOut"] = (
_timeString,
timeObject,
) => {
const { eventsByDate } = this.state;
const conflictsWithOtherEvents = this.state.events.some(
(event) =>
event.start === formatTimelineDate(_timeString) ||
event.end === formatTimelineDate(_timeString) ||
(event.start < formatTimelineDate(_timeString) &&
event.end > formatTimelineDate(_timeString)),
);
if (conflictsWithOtherEvents) {
return;
}
Alert.alert(
"Novo agendamento",
`Tem certeza que que criar um agendamento no dia ${convertFromISO(
timeObject.date,
)} às ${timeObject.hour}:${timeObject.minutes
.toString()
.padStart(2, "0")}?
`,
[
{
text: "Cancelar",
onPress: () => {
if (timeObject.date) {
eventsByDate[timeObject.date] = filter(
eventsByDate[timeObject.date],
(e) => e.id !== "draft",
);
this.setState({
eventsByDate,
});
}
},
},
{
text: "Agendar",
onPress: async () => {
if (timeObject.date) {
const draftEvent = find(eventsByDate[timeObject.date], {
id: "draft",
});
await useScheduleStore.getState().actions.setSchedule({
startAt: draftEvent?.start,
endAt: draftEvent?.end,
} as models.Schedule);
// Navigate to the other screen (adjust the navigation logic accordingly)
router.push("/pastoral-schedule/schedule-type/");
setTimeout(() => {
if (timeObject.date) {
eventsByDate[timeObject.date] = filter(
eventsByDate[timeObject.date],
(e) => e.id !== "draft",
);
this.setState({
eventsByDate,
});
}
}, 2000);
}
},
},
],
);
};
private timelineProps: Partial<TimelineProps> = {
format24h: true,
onBackgroundLongPress: this.createNewEvent,
onBackgroundLongPressOut: this.approveNewEvent,
onEventPress: this.onEventPress,
unavailableHours: [
{ start: 0, end: 16.5 },
{ start: 20, end: 24 },
],
overlapEventsSpacing: 8,
rightEdgeSpacing: 24,
};
render() {
const { currentDate, eventsByDate } = this.state;
return (
<CalendarProvider
date={currentDate}
onDateChanged={this.onDateChanged}
onMonthChange={this.onMonthChange}
showTodayButton
disabledOpacity={0.6}
theme={{
selectedDayBackgroundColor: Theme.colors.primary,
selectedDayTextColor: "#ffffff",
todayTextColor: Theme.colors.primary,
dotColor: Theme.colors.primary,
selectedDotColor: "#ffffff",
arrowColor: Theme.colors.primary,
monthTextColor: Theme.colors.primary,
textDayFontFamily: Theme.fonts.regular,
textMonthFontFamily: Theme.fonts.regular,
textDayHeaderFontFamily: Theme.fonts.regular,
}}
>
<ExpandableCalendar
minDate={getDate(-1)}
disableAllTouchEventsForDisabledDays
firstDay={1}
markedDates={this.marked}
theme={{
selectedDayBackgroundColor: Theme.colors.grayLight,
todayTextColor: Theme.colors.grayLight,
dotColor: Theme.colors.grayLight,
arrowColor: Theme.colors.primary,
monthTextColor: Theme.colors.primary,
textDayFontFamily: Theme.fonts.regular,
textMonthFontFamily: Theme.fonts.regular,
textDayHeaderFontFamily: Theme.fonts.regular,
}}
/>
<TimelineList
events={eventsByDate}
timelineProps={this.timelineProps}
showNowIndicator
scrollToNow
scrollToFirst
initialTime={INITIAL_TIME}
/>
</CalendarProvider>
);
}
}
Did you manage to fix this?
Did you manage to fix this?
just add this patch
diff --git a/node_modules/react-native-calendars/src/timeline/Timeline.js b/node_modules/react-native-calendars/src/timeline/Timeline.js
index 12c7851..9bfb96f 100644
--- a/node_modules/react-native-calendars/src/timeline/Timeline.js
+++ b/node_modules/react-native-calendars/src/timeline/Timeline.js
@@ -14,6 +14,7 @@ import TimelineHours from './TimelineHours';
import EventBlock from './EventBlock';
import NowIndicator from './NowIndicator';
import useTimelineOffset from './useTimelineOffset';
+import { set } from 'lodash';
const Timeline = (props) => {
const { format24h = true, start = 0, end = 24, date = '', events, onEventPress, onBackgroundLongPress, onBackgroundLongPressOut, renderEvent, theme, scrollToFirst, scrollToNow, initialTime, showNowIndicator, scrollOffset, onChangeOffset, overlapEventsSpacing = 0, rightEdgeSpacing = 0, unavailableHours, unavailableHoursColor, eventTapped, numberOfDays = 1, timelineLeftInset = 0 } = props;
const pageDates = useMemo(() => {
@@ -46,32 +47,30 @@ const Timeline = (props) => {
let initialPosition = 0;
if (scrollToNow) {
initialPosition = calcTimeOffset(HOUR_BLOCK_HEIGHT);
- }
- else if (scrollToFirst && packedEvents[0].length > 0) {
+ } else if (scrollToFirst && packedEvents[0].length > 0) {
initialPosition = min(map(packedEvents[0], 'top')) ?? 0;
- }
- else if (initialTime) {
+ } else if (initialTime) {
initialPosition = calcTimeOffset(HOUR_BLOCK_HEIGHT, initialTime.hour, initialTime.minutes);
}
if (initialPosition) {
- setTimeout(() => {
+
scrollView?.current?.scrollTo({
y: Math.max(0, initialPosition - HOUR_BLOCK_HEIGHT),
animated: true
});
- }, 0);
+
}
}, []);
- const _onEventPress = useCallback((dateIndex, eventIndex) => {
+ const _onEventPress = (dateIndex, eventIndex) => {
const event = packedEvents[dateIndex][eventIndex];
if (eventTapped) {
//TODO: remove after deprecation
eventTapped(event);
}
else {
- onEventPress?.(event);
+ onEventPress(event);
}
- }, [onEventPress, eventTapped]);
+ };
const renderEvents = (dayIndex) => {
const events = packedEvents[dayIndex].map((event, eventIndex) => {
const onEventPress = () => _onEventPress(dayIndex, eventIndex);
'