- Removed boxed background from grid tasks and added hover-only resize handle - Fixed vertical drop calculation using correct cell sizes - Aligned time column header perfectly using a structural ghost replica - Added collision detection to prevent dragging tasks over occupied slots
101 lines
3.1 KiB
TypeScript
101 lines
3.1 KiB
TypeScript
|
|
import { DAVClient } from 'tsdav';
|
|
|
|
// iCloud CalDAV Server URL
|
|
const ICLOUD_CALDAV_URL = 'https://caldav.icloud.com';
|
|
|
|
export interface AppleReminderList {
|
|
id: string; // URL
|
|
title: string;
|
|
color?: string;
|
|
}
|
|
|
|
/**
|
|
* Create a configured DAV client for Apple iCloud
|
|
*/
|
|
const createClient = (email: string, appSpecificPassword: string) => {
|
|
return new DAVClient({
|
|
serverUrl: ICLOUD_CALDAV_URL,
|
|
credentials: {
|
|
username: email,
|
|
password: appSpecificPassword,
|
|
},
|
|
authMethod: 'Basic',
|
|
defaultAccountType: 'caldav',
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Fetch all reminder lists (VTODO collections)
|
|
*/
|
|
export const fetchAppleReminderLists = async (email: string, appSpecificPassword: string): Promise<AppleReminderList[]> => {
|
|
try {
|
|
const client = createClient(email, appSpecificPassword);
|
|
await client.login();
|
|
|
|
const calendars = await client.fetchCalendars();
|
|
|
|
// Filter to VTODO collections (Reminders)
|
|
const reminderLists = calendars.filter(cal => {
|
|
const components: string[] = (cal as any).components || [];
|
|
return components.includes('VTODO');
|
|
});
|
|
|
|
return reminderLists.map(cal => ({
|
|
id: cal.url,
|
|
title: (cal.displayName as string) || 'Untitled List',
|
|
color: (cal as any).calendarColor,
|
|
}));
|
|
} catch (error) {
|
|
console.error('Error fetching Apple reminder lists:', error);
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Create a new reminder list (collection)
|
|
*/
|
|
export const createAppleReminderList = async (email: string, appSpecificPassword: string, title: string): Promise<AppleReminderList> => {
|
|
try {
|
|
const client = createClient(email, appSpecificPassword);
|
|
await client.login();
|
|
|
|
// tsdav's createDAVClient returns an object where we can use makeCalendar
|
|
// First we need a base URL. We can derive it from existing calendars.
|
|
const calendars = await client.fetchCalendars();
|
|
if (calendars.length === 0) {
|
|
throw new Error('No existing Apple calendars found to derive base URL');
|
|
}
|
|
|
|
// Deriving the base URL for new collections (usually parent of existing calendars)
|
|
const firstCalUrl = calendars[0].url;
|
|
const urlParts = firstCalUrl.split('/');
|
|
// Remove the last part (and trailing slash if exists)
|
|
if (firstCalUrl.endsWith('/')) urlParts.pop();
|
|
urlParts.pop();
|
|
const baseWebDavUrl = urlParts.join('/') + '/';
|
|
|
|
const newId = crypto.randomUUID();
|
|
const newCalendarUrl = `${baseWebDavUrl}${newId}/`;
|
|
|
|
// Create the calendar (reminder list)
|
|
await (client as any).makeCalendar({
|
|
url: newCalendarUrl,
|
|
props: {
|
|
'displayname': title,
|
|
'supported-calendar-component-set': {
|
|
'comp': { _attributes: { name: 'VTODO' } }
|
|
}
|
|
}
|
|
});
|
|
|
|
return {
|
|
id: newCalendarUrl,
|
|
title: title,
|
|
};
|
|
} catch (error) {
|
|
console.error('Error creating Apple reminder list:', error);
|
|
throw error;
|
|
}
|
|
};
|