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

Adding attendees to a meeting invitation #293

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,21 @@ Basic operations, you'll want to copy-paste this for testing purposes:
calOptions.url = "https://www.google.com";

// on iOS the success handler receives the event ID (since 4.3.6)
//To add meeting attendees jut add a JSON object similar to the following structure to the calOptionsParamater:
/*

{
"attendeesList": {
"ID": {
"firstName": "SOME",
"lastName": "ONE",
"emailAddress": "SOME_ONE@SOME_DOMAIN.com"
},
}

*/
window.plugins.calendar.createEventWithOptions(title,eventLocation,notes,startDate,endDate,calOptions,success,error);

// create an event interactively
window.plugins.calendar.createEventInteractively(title,eventLocation,notes,startDate,endDate,success,error);

Expand Down
63 changes: 22 additions & 41 deletions src/android/nl/xservices/plugins/Calendar.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@

import java.util.Date;
import java.util.TimeZone;
import java.text.SimpleDateFormat;

import static android.provider.CalendarContract.Events;

public class Calendar extends CordovaPlugin {
private static final String HAS_READ_PERMISSION = "hasReadPermission";
Expand Down Expand Up @@ -222,17 +219,15 @@ private void listCalendars() {
cordova.getThreadPool().execute(new Runnable() {
@Override
public void run() {
JSONArray jsonObject = new JSONArray();
try {
JSONArray activeCalendars = Calendar.this.getCalendarAccessor().getActiveCalendars();
if (activeCalendars == null) {
activeCalendars = new JSONArray();
}
PluginResult res = new PluginResult(PluginResult.Status.OK, activeCalendars);
callback.sendPluginResult(res);
jsonObject = Calendar.this.getCalendarAccessor().getActiveCalendars();
} catch (JSONException e) {
System.err.println("Exception: " + e.getMessage());
callback.error(e.getMessage());
}
PluginResult res = new PluginResult(PluginResult.Status.OK, jsonObject);
callback.sendPluginResult(res);
}
});
}
Expand Down Expand Up @@ -312,19 +307,6 @@ public void run() {
calIntent.putExtra("description", description);
calIntent.putExtra("calendar_id", argOptionsObject.optInt("calendarId", 1));

//set recurrence
String recurrence = getPossibleNullString("recurrence", argOptionsObject);
Long recurrenceEndTime = argOptionsObject.isNull("recurrenceEndTime") ? null : argOptionsObject.optLong("recurrenceEndTime");
int recurrenceInterval = argOptionsObject.optInt("recurrenceInterval");
if (recurrence != null) {
if (recurrenceEndTime == null) {
calIntent.putExtra(Events.RRULE, "FREQ=" + recurrence.toUpperCase() + ";INTERVAL=" + recurrenceInterval);
} else {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'hhmmss'Z'");
calIntent.putExtra(Events.RRULE, "FREQ=" + recurrence.toUpperCase() + ";INTERVAL=" + recurrenceInterval + ";UNTIL=" + sdf.format(new Date(recurrenceEndTime)));
}
}

Calendar.this.cordova.startActivityForResult(Calendar.this, calIntent, RESULT_CODE_CREATE);
}
});
Expand Down Expand Up @@ -443,19 +425,19 @@ private void createEvent(JSONArray args) {
public void run() {
try {
final String createdEventID = getCalendarAccessor().createEvent(
null,
getPossibleNullString("title", argObject),
argObject.getLong("startTime"),
argObject.getLong("endTime"),
getPossibleNullString("notes", argObject),
getPossibleNullString("location", argObject),
argOptionsObject.optLong("firstReminderMinutes", -1),
argOptionsObject.optLong("secondReminderMinutes", -1),
getPossibleNullString("recurrence", argOptionsObject),
argOptionsObject.optInt("recurrenceInterval"),
argOptionsObject.optLong("recurrenceEndTime"),
argOptionsObject.optInt("calendarId", 1),
getPossibleNullString("url", argOptionsObject));
null,
getPossibleNullString("title", argObject),
argObject.getLong("startTime"),
argObject.getLong("endTime"),
getPossibleNullString("notes", argObject),
getPossibleNullString("location", argObject),
argOptionsObject.optLong("firstReminderMinutes"),
argOptionsObject.optLong("secondReminderMinutes"),
getPossibleNullString("recurrence", argOptionsObject),
argOptionsObject.optInt("recurrenceInterval"),
argOptionsObject.optLong("recurrenceEndTime"),
argOptionsObject.optInt("calendarId", 1),
getPossibleNullString("url", argOptionsObject), argOptionsObject.optJSONObject("attendees"));
callback.success(createdEventID);
} catch (JSONException e) {
e.printStackTrace();
Expand All @@ -471,7 +453,7 @@ public void run() {
private static String getPossibleNullString(String param, JSONObject from) {
return from.isNull(param) || "null".equals(from.optString(param)) ? null : from.optString(param);
}

private void listEventsInRange(JSONArray args) {
// note that if the dev didn't call requestReadPermission before calling this method and calendarPermissionGranted returns false,
// the app will ask permission and this method needs to be invoked again (done for backward compat).
Expand All @@ -481,7 +463,7 @@ private void listEventsInRange(JSONArray args) {
return;
}
try {
final JSONObject jsonFilter = args.getJSONObject(0);
final JSONObject jsonFilter = args.getJSONObject(0);
JSONArray result = new JSONArray();
long input_start_date = jsonFilter.optLong("startTime");
long input_end_date = jsonFilter.optLong("endTime");
Expand All @@ -492,7 +474,7 @@ private void listEventsInRange(JSONArray args) {
} else {
l_eventUri = Uri.parse("content://calendar/instances/when/" + String.valueOf(input_start_date) + "/" + String.valueOf(input_end_date));
}

cordova.getThreadPool().execute(new Runnable() {
@Override
public void run() {
Expand All @@ -513,7 +495,7 @@ public void run() {
calendar_end.setTime(date_end);

//projection of DB columns
String[] l_projection = new String[]{"calendar_id", "title", "begin", "end", "eventLocation", "allDay", "_id"};
String[] l_projection = new String[]{"calendar_id", "title", "begin", "end", "eventLocation", "allDay"};
Copy link
Owner

Choose a reason for hiding this comment

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

Where did "_id" go?

Copy link
Author

Choose a reason for hiding this comment

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

I am not sure, I didn't change this area !!

I will check tomorrow
On May 23, 2016 10:43 PM, "Eddy Verbruggen" [email protected]
wrote:

In src/android/nl/xservices/plugins/Calendar.java
#293 (comment)
:

@@ -513,7 +495,7 @@ public void run() {
calendar_end.setTime(date_end);

       //projection of DB columns
  •      String[] l_projection = new String[]{"calendar_id", "title", "begin", "end", "eventLocation", "allDay", "_id"};
    
  •      String[] l_projection = new String[]{"calendar_id", "title", "begin", "end", "eventLocation", "allDay"};
    

Where did "_id" go?


You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub
https://github.com/EddyVerbruggen/Calendar-PhoneGap-Plugin/pull/293/files/4660ce3b561ddb2231a2a84a8126fba2c74ba30b#r64275947


//actual query
Cursor cursor = contentResolver.query(
Expand All @@ -537,7 +519,6 @@ public void run() {
i++,
new JSONObject()
.put("calendar_id", cursor.getString(cursor.getColumnIndex("calendar_id")))
.put("event_id", cursor.getString(cursor.getColumnIndex("_id")))
.put("title", cursor.getString(cursor.getColumnIndex("title")))
.put("dtstart", cursor.getLong(cursor.getColumnIndex("begin")))
.put("dtend", cursor.getLong(cursor.getColumnIndex("end")))
Expand All @@ -559,7 +540,7 @@ public void run() {
callback.error(e.getMessage());
}
}

public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RESULT_CODE_CREATE) {
if (resultCode == Activity.RESULT_OK || resultCode == Activity.RESULT_CANCELED) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,6 @@ public final JSONArray getActiveCalendars() throws JSONException {
},
this.getKey(KeyIndex.CALENDARS_VISIBLE) + "=1", null, null
);
if (cursor == null) {
return null;
}
JSONArray calendarsWrapper = new JSONArray();
if (cursor.moveToFirst()) {
do {
Expand Down Expand Up @@ -432,7 +429,8 @@ public boolean deleteEvent(Uri eventsUri, long startFrom, long startTo, String t

public String createEvent(Uri eventsUri, String title, long startTime, long endTime, String description,
String location, Long firstReminderMinutes, Long secondReminderMinutes,
String recurrence, int recurrenceInterval, Long recurrenceEndTime, Integer calendarId, String url) {
String recurrence, int recurrenceInterval, Long recurrenceEndTime, Integer calendarId, String url,
JSONObject attendeesList) throws JSONException{
ContentResolver cr = this.cordova.getActivity().getContentResolver();
ContentValues values = new ContentValues();
final boolean allDayEvent = isAllDayEvent(new Date(startTime), new Date(endTime));
Expand All @@ -457,34 +455,52 @@ public String createEvent(Uri eventsUri, String title, long startTime, long endT
}
}
values.put(Events.DESCRIPTION, description);
values.put(Events.HAS_ALARM, firstReminderMinutes > -1 || secondReminderMinutes > -1 ? 1 : 0);
values.put(Events.HAS_ALARM, (firstReminderMinutes == null && secondReminderMinutes == null) ? 0 : 1);
values.put(Events.CALENDAR_ID, calendarId);
values.put(Events.EVENT_LOCATION, location);

if (recurrence != null) {
if (recurrenceEndTime == null) {
values.put(Events.RRULE, "FREQ=" + recurrence.toUpperCase() + ";INTERVAL=" + recurrenceInterval);
} else {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'hhmmss'Z'");
values.put(Events.RRULE, "FREQ=" + recurrence.toUpperCase() + ";INTERVAL=" + recurrenceInterval + ";UNTIL=" + sdf.format(new Date(recurrenceEndTime)));
final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
values.put(Events.RRULE, "FREQ=" + recurrence.toUpperCase() + ";INTERVAL=" + recurrenceInterval + ";UNTIL=" + sdf.format(new Date(recurrenceEndTime))+"T000000Z");
}
}



// runtime exceptions are dealt with by the caller
Uri uri = cr.insert(eventsUri, values);
String createdEventID = uri.getLastPathSegment();

if(attendeesList != null){
Iterator keys = attendeesList.keys();
values.clear();
values.put(CalendarContract.Attendees.EVENT_ID, createdEventID);
values.put(CalendarContract.Attendees.ATTENDEE_TYPE, CalendarContract.Attendees.TYPE_REQUIRED);

while(keys.hasNext()){
JSONObject attendee = attendeesList.getJSONObject(keys.next().toString());
values.put(CalendarContract.Attendees.ATTENDEE_NAME, attendee.getString("firstName") + " " + attendee.getString("lastName"));
values.put(CalendarContract.Attendees.ATTENDEE_EMAIL, attendee.getString("emailAddress"));
cr.insert(CalendarContract.Attendees.CONTENT_URI, values);
}

}

Log.d(LOG_TAG, "Created event with ID " + createdEventID);

try {
if (firstReminderMinutes > -1) {
if (firstReminderMinutes != null) {
ContentValues reminderValues = new ContentValues();
reminderValues.put("event_id", Long.parseLong(uri.getLastPathSegment()));
reminderValues.put("minutes", firstReminderMinutes);
reminderValues.put("method", 1);
cr.insert(Uri.parse(CONTENT_PROVIDER + CONTENT_PROVIDER_PATH_REMINDERS), reminderValues);
}

if (secondReminderMinutes > -1) {
if (secondReminderMinutes != null) {
ContentValues reminderValues = new ContentValues();
reminderValues.put("event_id", Long.parseLong(uri.getLastPathSegment()));
reminderValues.put("minutes", secondReminderMinutes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
import android.provider.CalendarContract.Events;
import android.provider.CalendarContract.Instances;
import org.apache.cordova.CordovaInterface;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.Integer;
import java.util.EnumMap;
Expand Down Expand Up @@ -122,9 +124,9 @@ public boolean deleteEvent(Uri eventsUri, long startFrom, long startTo, String t
public String createEvent(Uri eventsUri, String title, long startTime, long endTime,
String description, String location, Long firstReminderMinutes, Long secondReminderMinutes,
String recurrence, int recurrenceInterval, Long recurrenceEndTime, Integer calendarId,
String url) {
String url, JSONObject attendeesList) throws JSONException{
eventsUri = eventsUri == null ? Uri.parse(CONTENT_PROVIDER + CONTENT_PROVIDER_PATH_EVENTS) : eventsUri;
return super.createEvent(eventsUri, title, startTime, endTime, description, location,
firstReminderMinutes, secondReminderMinutes, recurrence, recurrenceInterval, recurrenceEndTime, calendarId, url);
firstReminderMinutes, secondReminderMinutes, recurrence, recurrenceInterval, recurrenceEndTime, calendarId, url, attendeesList);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
import android.net.Uri;
import android.os.Build;
import org.apache.cordova.CordovaInterface;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.EnumMap;

Expand Down Expand Up @@ -124,10 +126,10 @@ public boolean deleteEvent(Uri eventsUri, long startFrom, long startTo, String t
public String createEvent(Uri eventsUri, String title, long startTime, long endTime,
String description, String location, Long firstReminderMinutes, Long secondReminderMinutes,
String recurrence, int recurrenceInterval, Long recurrenceEndTime, Integer calendarId,
String url) {
String url, JSONObject attendeesList) throws JSONException{
eventsUri = eventsUri == null ? Uri.parse(CONTENT_PROVIDER_PRE_FROYO + CONTENT_PROVIDER_PATH_EVENTS) : eventsUri;
return super.createEvent(eventsUri, title, startTime, endTime, description, location,
firstReminderMinutes, secondReminderMinutes, recurrence, recurrenceInterval, recurrenceEndTime, calendarId, url);
firstReminderMinutes, secondReminderMinutes, recurrence, recurrenceInterval, recurrenceEndTime, calendarId, url, attendeesList);
}

}
31 changes: 26 additions & 5 deletions src/ios/Calendar.m
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,6 @@ - (NSMutableArray*) eventsToDataArray: (NSArray*)matchingEvents {
event.calendar.title, @"calendar",
[df stringFromDate:event.startDate], @"startDate",
[df stringFromDate:event.endDate], @"endDate",
[df stringFromDate:event.lastModifiedDate], @"lastModifiedDate",
nil];
Copy link
Owner

Choose a reason for hiding this comment

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

Removed by accident?

// optional fields
if (event.location != nil) {
Expand Down Expand Up @@ -459,6 +458,7 @@ - (void)createEventWithOptions:(CDVInvokedUrlCommand*)command {
NSNumber* startTime = [options objectForKey:@"startTime"];
NSNumber* endTime = [options objectForKey:@"endTime"];


NSDictionary* calOptions = [options objectForKey:@"options"];
NSNumber* firstReminderMinutes = [calOptions objectForKey:@"firstReminderMinutes"];
NSNumber* secondReminderMinutes = [calOptions objectForKey:@"secondReminderMinutes"];
Expand All @@ -467,6 +467,7 @@ - (void)createEventWithOptions:(CDVInvokedUrlCommand*)command {
NSNumber* recurrenceIntervalAmount = [calOptions objectForKey:@"recurrenceInterval"];
NSString* calendarName = [calOptions objectForKey:@"calendarName"];
NSString* url = [calOptions objectForKey:@"url"];
NSDictionary* attendeesList = [calOptions objectForKey:@"attendees"];

[self.commandDelegate runInBackground: ^{
EKEvent *myEvent = [EKEvent eventWithEventStore: self.eventStore];
Expand All @@ -484,7 +485,7 @@ - (void)createEventWithOptions:(CDVInvokedUrlCommand*)command {
myEvent.location = location;
myEvent.notes = notes;
myEvent.startDate = myStartDate;

int duration = _endInterval - _startInterval;
int moduloDay = duration % (60*60*24);
if (moduloDay == 0) {
Expand All @@ -493,6 +494,7 @@ - (void)createEventWithOptions:(CDVInvokedUrlCommand*)command {
} else {
myEvent.endDate = [NSDate dateWithTimeIntervalSince1970:_endInterval];
}


EKCalendar* calendar = nil;
CDVPluginResult *pluginResult = nil;
Expand Down Expand Up @@ -545,8 +547,29 @@ - (void)createEventWithOptions:(CDVInvokedUrlCommand*)command {
}
[myEvent addRecurrenceRule:rule];
}

if (attendeesList != (id)[NSNull null]) {
NSMutableArray *attendees = [NSMutableArray new];
for(id attendee in attendeesList){
//Initialize a EKAttendee object, which is not accessible and inherits from EKParticipant
Class className = NSClassFromString(@"EKAttendee");
id attendeeObject = [className new];
//Set the properties of this attendee using setValue:forKey:
[attendeeObject setValue:[[attendeesList objectForKey:attendee] objectForKey:@"firstName"] forKey:@"firstName"];
[attendeeObject setValue:[[attendeesList objectForKey:attendee] objectForKey:@"lastName"] forKey:@"lastName"];
[attendeeObject setValue:[[attendeesList objectForKey:attendee] objectForKey:@"emailAddress"] forKey:@"emailAddress"];
[attendees addObject:attendeeObject];
}

//Finally, add the invitees to the event
[myEvent setValue:attendees forKey:@"attendees"];
}



NSError *error = nil;


[self.eventStore saveEvent:myEvent span:EKSpanThisEvent error:&error];

if (error) {
Expand Down Expand Up @@ -660,9 +683,7 @@ - (void) createEventInteractively:(CDVInvokedUrlCommand*)command {
controller.event = myEvent;
controller.eventStore = self.eventStore;
controller.editViewDelegate = self;
dispatch_async(dispatch_get_main_queue(), ^{
[self.viewController presentViewController:controller animated:YES completion:nil];
});
[self.viewController presentViewController:controller animated:YES completion:nil];
}];
}

Expand Down