@cometchat/chat-uikit-react-native
Version:
Ready-to-use Chat UI Components for React Native
199 lines (179 loc) • 6.3 kB
text/typescript
//@ts-ignore
import { DateTime } from "../libs/luxon/src/luxon";
import { anyObject } from "./TypeUtils";
export const convert24to12 = (time: any) => {
if (time && typeof time === "string") {
let [hours, minutes] = time.split(":"); // split hours and minutes
let suffix = +hours >= 12 ? "PM" : "AM"; // set suffix as AM or PM
hours = (+hours % 12 || 12).toString(); // convert hours from 24 to 12 hour format
return `${hours}:${minutes} ${suffix}`; // return the format as a string
}
return "";
};
export const addMinutes = (time: string, minutes: number) => {
// create a new date object
const date = new Date();
// split the time string into hours and minutes
const parts = time.split(":");
// set the time on the date object
date.setHours(+parts[0]);
date.setMinutes(+parts[1]);
// add the minutes
date.setMinutes(date.getMinutes() + minutes);
// format and return the new time
return `${date
.getHours()
.toString()
.padStart(2, "0")}${date.getMinutes().toString().padStart(2, "0")}`;
};
export const convertToATimeZone = (
time: number | string,
timeZone: string,
formats: "yyyy-MM-dd" | "HHmm" | string,
usingFunc: "fromMillis" | "fromFormat" | "fromISO",
fromFormat?: string
) => {
if (usingFunc === "fromMillis" && typeof time === "number") {
//@ts-ignore
let timeZoneTime = DateTime.fromMillis(time, { zone: timeZone });
let localTime = timeZoneTime.setZone();
return localTime.toFormat(formats);
}
if (usingFunc === "fromFormat" && typeof time === "string") {
//@ts-ignore
let timeZoneTime = DateTime.fromFormat(time, fromFormat, {
zone: timeZone,
});
let localTime = timeZoneTime.setZone();
return localTime.toFormat(formats);
}
if (usingFunc === "fromISO" && typeof time === "string") {
//@ts-ignore
let timeZoneTime = DateTime.fromISO(time, {
zone: timeZone,
});
let localTime = timeZoneTime.setZone();
if (formats === "toISO") {
return localTime;
}
return localTime.toFormat(formats);
}
return "";
};
export const convertToLocalTimeZone = (
time: string,
timeZone: string,
formats: "yyyy-MM-dd" | "HHmm" | string
) => {
const isoTime = DateTime.fromISO(time, {
zone: timeZone,
});
const utcTime = isoTime.toUTC();
const timeZoneOffsetInMins = new Date().getTimezoneOffset();
const localTime = utcTime
.minus({ minutes: timeZoneOffsetInMins })
.toFormat(formats);
return localTime;
};
export const convertDate = (dateStr: any) => {
const year = dateStr.slice(0, 4);
const month = dateStr.slice(4, 6);
const day = dateStr.slice(6, 8);
const time = dateStr.slice(9);
return `${year}-${month}-${day}T${time.slice(0, 2)}:${time.slice(
2,
4
)}:${time.slice(4)}`;
};
export const getFormatedDateString = ({
date,
format,
}: {
date: string | Date | number;
format: "YYYY-DD-MM" | "HHmm" | string;
}) => {
if (typeof date === "number") {
return DateTime.fromMillis(date).toFormat(format);
}
if (typeof date === "object") {
return DateTime.fromISO(date.toISOString()).toFormat(format);
}
return "";
};
export const getMinSlotsFromRange = ({
startTime,
endTime,
slotDuration = 30,
selectedSlots = [],
bufferDuration = 0,
}:any) => {
const slots: any[] = []; // Array to hold all available slots
// Convert start time and end time (HHMM format) to total minutes
let currentStartMinutes =
Number(startTime.slice(0, 2)) * 60 + Number(startTime.slice(2));
let endMinutesTotal =
Number(endTime.slice(0, 2)) * 60 + Number(endTime.slice(2));
if (endMinutesTotal === 1439) endMinutesTotal += 1;
// Add buffer time if the availability starts immediately after a blocked time
const prevSlot = selectedSlots.find(
(slot: any) =>
Number(slot.endTime!.slice(0, 2)) * 60 +
Number(slot.endTime!.slice(2)) ===
currentStartMinutes
);
if (prevSlot) currentStartMinutes += bufferDuration;
// Keep generating slots until the end of the availability range
while (currentStartMinutes + slotDuration <= endMinutesTotal) {
let conflictSlot: anyObject | null = null;
// Iterate over each selected slot to find a conflict
for (let i = 0; i < selectedSlots.length; i++) {
const { startTime: start, endTime: end } = selectedSlots[i];
const slotStart = Number(start.slice(0, 2)) * 60 + Number(start.slice(2));
const slotEnd = Number(end.slice(0, 2)) * 60 + Number(end.slice(2));
let currentEndMinutes = currentStartMinutes + slotDuration;
// The current slot is within the selected slot or
// The current slot starts before and ends after the start of the selected slot or
// The current slot starts before the end of the selected slot but ends after
if (
(currentStartMinutes >= slotStart && currentEndMinutes <= slotEnd) ||
(currentStartMinutes < slotStart && currentEndMinutes > slotStart) ||
(currentStartMinutes < slotEnd && currentEndMinutes > slotEnd)
) {
conflictSlot = selectedSlots[i];
break;
}
}
// If there is no conflict, add the slot
if (!conflictSlot) {
slots.push(
`${String(Math.floor(currentStartMinutes / 60)).padStart(
2,
"0"
)}:${String(currentStartMinutes % 60).padStart(2, "0")}`
);
} else {
// If a conflict arises, remove the last added slot if it is not possible to add the buffer duration to it without overlapping the selected slot
if (
slots.length &&
Number(conflictSlot.startTime.slice(0, 2)) * 60 +
Number(conflictSlot.startTime.slice(2)) <
Number(slots[slots.length - 1].slice(0, 2)) * 60 +
Number(slots[slots.length - 1].slice(3)) +
slotDuration +
bufferDuration
) {
slots.pop();
}
// Skip to the end of the conflict slot and continue to the next iteration
currentStartMinutes =
Number(conflictSlot.endTime.slice(0, 2)) * 60 +
Number(conflictSlot.endTime.slice(2)) +
bufferDuration;
continue;
}
// Move to the next slot by adding the slot duration
currentStartMinutes += slotDuration;
}
// Return all available slots
return slots;
};