From 332065c106ae812db1c5976ac00a936ac53150f2 Mon Sep 17 00:00:00 2001 From: prashantsaini1 Date: Mon, 2 Dec 2024 23:24:24 +0530 Subject: [PATCH 01/11] feat(android): added new methods in CalendarProxy for bulk operations --- .../titanium/calendar/CalendarProxy.java | 145 ++++++++++++++++++ .../titanium/calendar/CalendarUtils.java | 86 +++++++++++ .../modules/titanium/calendar/EventProxy.java | 67 ++------ 3 files changed, 244 insertions(+), 54 deletions(-) create mode 100644 android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarUtils.java diff --git a/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java b/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java index 86082882a18..e9fc47124c0 100644 --- a/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java +++ b/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java @@ -7,9 +7,13 @@ package ti.modules.titanium.calendar; +import static ti.modules.titanium.calendar.EventProxy.getEventsUri; + import java.util.ArrayList; import java.util.Calendar; import java.util.Date; +import java.util.HashMap; +import java.util.Map; import org.appcelerator.kroll.KrollDict; import org.appcelerator.kroll.KrollProxy; @@ -19,11 +23,17 @@ import android.app.Activity; import android.content.ContentResolver; +import android.content.ContentValues; import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; import android.os.Build; +import android.provider.CalendarContract; import android.text.format.DateUtils; +import android.content.ContentProviderOperation; +import android.content.ContentProviderResult; +import android.content.OperationApplicationException; +import android.os.RemoteException; @Kroll.proxy(parentModule = CalendarModule.class) public class CalendarProxy extends KrollProxy @@ -188,12 +198,147 @@ public EventProxy getEventById(int id) return null; } + @Kroll.method + public EventProxy[] getEventsById(Object args) + { + ArrayList events = new ArrayList<>(); + + if (args instanceof Object[] eventIds && eventIds.length > 0) { + String query = CalendarUtils.prepareQuerySelection("_id", eventIds.length); + String[] queryArgs = CalendarUtils.prepareQueryArguments(eventIds); + + events.addAll(EventProxy.queryEvents(query, queryArgs)); + } + + return events.toArray(new EventProxy[0]); + } + @Kroll.method public EventProxy createEvent(KrollDict data) { return EventProxy.createEvent(this, data); } + @Kroll.method + public EventProxy[] createEvents(Object data) + { + // Validate arguments to be an array. + if (!(data instanceof Object[] dataList && dataList.length > 0)) { + Log.e(TAG, "Argument expected to be an array."); + return null; + } + + // Check for permissions. + ContentResolver contentResolver = TiApplication.getInstance().getContentResolver(); + if (!CalendarProxy.hasCalendarPermissions()) { + Log.e(TAG, "Calendar permissions are missing."); + return null; + } + + ArrayList operations = new ArrayList<>(); + ArrayList eventProxies = new ArrayList<>(); + Map proxyResultIndexMapping = new HashMap<>(); + + for (int i = 0, firstIndex = 0; i < dataList.length; i++) { + KrollDict krollDict = new KrollDict((HashMap) dataList[i]); + + EventProxy eventProxy = new EventProxy(); + ContentValues contentValues = CalendarUtils.createContentValues(this, krollDict, eventProxy); + + // We cannot pass null data to ContentProviderOperation. + // Necessary to keep track of non-null items later. + if (contentValues == null) { + eventProxies.add(null); + Log.e(TAG, "Title was not created, no title found for event"); + continue; + } + + ContentProviderOperation.Builder builder = ContentProviderOperation + .newInsert(CalendarContract.Events.CONTENT_URI) + .withValues(contentValues); + + operations.add(builder.build()); + eventProxies.add(eventProxy); + + proxyResultIndexMapping.put(i, firstIndex); + firstIndex++; + } + + try { + // Execute the batch operation + ContentProviderResult[] results = contentResolver.applyBatch( + getEventsUri().getAuthority(), + operations + ); + + // Find non-null proxies and map their IDs + for (int proxyIndex : proxyResultIndexMapping.keySet()) { + int proxyIndexInResults = proxyResultIndexMapping.get(proxyIndex); + Uri eventUri = results[proxyIndexInResults].uri; + + if (eventUri != null) { + // Set event id to proxy. + eventProxies.get(proxyIndex).id = eventUri.getLastPathSegment(); + } else { + // Event failed to get a proper URI path, should set to null in this case too. + eventProxies.set(proxyIndex, null); + } + } + + return eventProxies.toArray(new EventProxy[0]); + + } catch (RemoteException | OperationApplicationException e) { + Log.e(TAG, "Batch insert operation failed: " + e.getMessage()); + return null; + } + } + + @Kroll.method + public int deleteEvents(Object args) + { + int deletedCount = 0; + + // Validate arguments to be an array. + if (!(args instanceof Object[] eventIds && eventIds.length > 0)) { + Log.e(TAG, "Argument expected to be an array."); + return deletedCount; + } + + // Check for permissions. + ContentResolver contentResolver = TiApplication.getInstance().getContentResolver(); + if (!CalendarProxy.hasCalendarPermissions()) { + Log.e(TAG, "Calendar permissions are missing."); + return deletedCount; + } + + String query = CalendarUtils.prepareQuerySelection("_id", eventIds.length); + String[] queryArgs = CalendarUtils.prepareQueryArguments(eventIds); + + ArrayList operations = new ArrayList<>(); + ContentProviderOperation.Builder builder = ContentProviderOperation + .newDelete(CalendarContract.Events.CONTENT_URI) + .withSelection(query, queryArgs); + + operations.add(builder.build()); + + try { + // Execute the batch operation + ContentProviderResult[] results = contentResolver.applyBatch( + getEventsUri().getAuthority(), + operations + ); + + if (results.length > 0 && results[0].count != null) { + deletedCount = results[0].count; + } + + } catch (RemoteException | OperationApplicationException e) { + Log.e(TAG, "Batch deletion failed: " + e.getMessage()); + } + + return deletedCount; + } + @Kroll.getProperty public String getName() { diff --git a/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarUtils.java b/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarUtils.java new file mode 100644 index 00000000000..298663554cd --- /dev/null +++ b/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarUtils.java @@ -0,0 +1,86 @@ +package ti.modules.titanium.calendar; + +import android.content.ContentValues; +import android.provider.CalendarContract; +import android.text.TextUtils; + +import org.appcelerator.kroll.KrollDict; +import org.appcelerator.titanium.TiC; +import org.appcelerator.titanium.util.TiConvert; + +import java.util.Collections; +import java.util.Date; + +public class CalendarUtils +{ + public static final String TAG = "CalendarUtils"; + + // Build the selection string for IN clause. + public static String prepareQuerySelection(String columnName, int limit) + { + return columnName + " IN (" + TextUtils.join(", ", Collections.nCopies(limit, "?")) + ")"; + } + + // Creates String[] for selectionArgs. + public static String[] prepareQueryArguments(Object[] data) + { + String[] queryArgs = new String[data.length]; + for (int i = 0; i < data.length; i++) { + queryArgs[i] = String.valueOf(data[i]); + } + return queryArgs; + } + + public static ContentValues createContentValues(CalendarProxy calendar, KrollDict data, EventProxy event) + { + if (!data.containsKey("title")) { + return null; + } + + ContentValues contentValues = new ContentValues(); + contentValues.put("hasAlarm", 1); + contentValues.put("hasExtendedProperties", 1); + + event.title = TiConvert.toString(data, "title"); + contentValues.put("title", event.title); + contentValues.put("calendar_id", calendar.getId()); + contentValues.put(CalendarContract.Events.EVENT_TIMEZONE, new Date().toString()); + + if (data.containsKey(TiC.PROPERTY_LOCATION)) { + event.location = TiConvert.toString(data, TiC.PROPERTY_LOCATION); + contentValues.put(CalendarModule.EVENT_LOCATION, event.location); + } + if (data.containsKey("description")) { + event.description = TiConvert.toString(data, "description"); + contentValues.put("description", event.description); + } + if (data.containsKey("begin")) { + event.begin = TiConvert.toDate(data, "begin"); + if (event.begin != null) { + contentValues.put("dtstart", event.begin.getTime()); + } + } + if (data.containsKey("end")) { + event.end = TiConvert.toDate(data, "end"); + if (event.end != null) { + contentValues.put("dtend", event.end.getTime()); + } + } + if (data.containsKey("allDay")) { + event.allDay = TiConvert.toBoolean(data, "allDay"); + contentValues.put("allDay", event.allDay ? 1 : 0); + } + + if (data.containsKey("hasExtendedProperties")) { + event.hasExtendedProperties = TiConvert.toBoolean(data, "hasExtendedProperties"); + contentValues.put("hasExtendedProperties", event.hasExtendedProperties ? 1 : 0); + } + + if (data.containsKey("hasAlarm")) { + event.hasAlarm = TiConvert.toBoolean(data, "hasAlarm"); + contentValues.put("hasAlarm", event.hasAlarm ? 1 : 0); + } + + return contentValues; + } +} diff --git a/android/modules/calendar/src/java/ti/modules/titanium/calendar/EventProxy.java b/android/modules/calendar/src/java/ti/modules/titanium/calendar/EventProxy.java index 9ad71100316..5a5c8f39b43 100644 --- a/android/modules/calendar/src/java/ti/modules/titanium/calendar/EventProxy.java +++ b/android/modules/calendar/src/java/ti/modules/titanium/calendar/EventProxy.java @@ -55,9 +55,9 @@ public EventProxy() super(); } - public static String getEventsUri() + public static Uri getEventsUri() { - return CalendarProxy.getBaseCalendarUri() + "/events"; + return Events.CONTENT_URI; } public static String getInstancesWhenUri() @@ -72,7 +72,7 @@ public static String getExtendedPropertiesUri() public static ArrayList queryEvents(String query, String[] queryArgs) { - return queryEvents(Uri.parse(getEventsUri()), query, queryArgs, "dtstart ASC"); + return queryEvents(getEventsUri(), query, queryArgs, "dtstart ASC"); } public static ArrayList queryEventsBetweenDates(long date1, long date2, String query, @@ -146,7 +146,7 @@ public void save() contentValues.put(Events.RRULE, ruleToSave); ContentResolver contentResolver = TiApplication.getInstance().getContentResolver(); try { - contentResolver.update(Events.CONTENT_URI, contentValues, Events._ID + "=?", new String[] { id }); + contentResolver.update(getEventsUri(), contentValues, Events._ID + "=?", new String[] { id }); } catch (IllegalArgumentException e) { Log.e(TAG, "Invalid event recurrence rule."); } @@ -203,60 +203,20 @@ public static EventProxy createEvent(CalendarProxy calendar, KrollDict data) if (!CalendarProxy.hasCalendarPermissions()) { return null; } - EventProxy event = new EventProxy(); - ContentValues eventValues = new ContentValues(); - eventValues.put("hasAlarm", 1); - eventValues.put("hasExtendedProperties", 1); + EventProxy event = new EventProxy(); + ContentValues contentValues = CalendarUtils.createContentValues(calendar, data, event); - if (!data.containsKey("title")) { + if (contentValues == null) { Log.e(TAG, "Title was not created, no title found for event"); return null; } - event.title = TiConvert.toString(data, "title"); - eventValues.put("title", event.title); - eventValues.put("calendar_id", calendar.getId()); - eventValues.put(Events.EVENT_TIMEZONE, new Date().toString()); - - if (data.containsKey(TiC.PROPERTY_LOCATION)) { - event.location = TiConvert.toString(data, TiC.PROPERTY_LOCATION); - eventValues.put(CalendarModule.EVENT_LOCATION, event.location); - } - if (data.containsKey("description")) { - event.description = TiConvert.toString(data, "description"); - eventValues.put("description", event.description); - } - if (data.containsKey("begin")) { - event.begin = TiConvert.toDate(data, "begin"); - if (event.begin != null) { - eventValues.put("dtstart", event.begin.getTime()); - } - } - if (data.containsKey("end")) { - event.end = TiConvert.toDate(data, "end"); - if (event.end != null) { - eventValues.put("dtend", event.end.getTime()); - } - } - if (data.containsKey("allDay")) { - event.allDay = TiConvert.toBoolean(data, "allDay"); - eventValues.put("allDay", event.allDay ? 1 : 0); - } - - if (data.containsKey("hasExtendedProperties")) { - event.hasExtendedProperties = TiConvert.toBoolean(data, "hasExtendedProperties"); - eventValues.put("hasExtendedProperties", event.hasExtendedProperties ? 1 : 0); - } - - if (data.containsKey("hasAlarm")) { - event.hasAlarm = TiConvert.toBoolean(data, "hasAlarm"); - eventValues.put("hasAlarm", event.hasAlarm ? 1 : 0); + Uri eventUri = contentResolver.insert(Uri.parse(CalendarProxy.getBaseCalendarUri() + "/events"), contentValues); + if (eventUri == null) { + return null; } - Uri eventUri = contentResolver.insert(Uri.parse(CalendarProxy.getBaseCalendarUri() + "/events"), eventValues); - Log.d("TiEvents", "created event with uri: " + eventUri, Log.DEBUG_MODE); - String eventId = eventUri.getLastPathSegment(); event.id = eventId; @@ -565,13 +525,12 @@ public boolean remove() ContentResolver contentResolver = TiApplication.getInstance().getContentResolver(); try { - Uri deleteUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, TiConvert.toInt(id)); - contentResolver.delete(deleteUri, null, null); + Uri deleteUri = ContentUris.withAppendedId(getEventsUri(), TiConvert.toInt(id)); + int deletedCount = contentResolver.delete(deleteUri, null, null); + return deletedCount == 1; } catch (IllegalArgumentException e) { return false; } - - return true; } @Override From cc5a1cab1e0a17926d39e43ebaf2c7193afad270 Mon Sep 17 00:00:00 2001 From: prashantsaini1 Date: Tue, 3 Dec 2024 01:03:08 +0530 Subject: [PATCH 02/11] chore: use constant properties --- .../titanium/calendar/CalendarUtils.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarUtils.java b/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarUtils.java index 298663554cd..a1693d76c02 100644 --- a/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarUtils.java +++ b/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarUtils.java @@ -33,7 +33,7 @@ public static String[] prepareQueryArguments(Object[] data) public static ContentValues createContentValues(CalendarProxy calendar, KrollDict data, EventProxy event) { - if (!data.containsKey("title")) { + if (!data.containsKey(TiC.PROPERTY_TITLE)) { return null; } @@ -41,8 +41,8 @@ public static ContentValues createContentValues(CalendarProxy calendar, KrollDic contentValues.put("hasAlarm", 1); contentValues.put("hasExtendedProperties", 1); - event.title = TiConvert.toString(data, "title"); - contentValues.put("title", event.title); + event.title = TiConvert.toString(data, TiC.PROPERTY_TITLE); + contentValues.put(TiC.PROPERTY_TITLE, event.title); contentValues.put("calendar_id", calendar.getId()); contentValues.put(CalendarContract.Events.EVENT_TIMEZONE, new Date().toString()); @@ -50,22 +50,26 @@ public static ContentValues createContentValues(CalendarProxy calendar, KrollDic event.location = TiConvert.toString(data, TiC.PROPERTY_LOCATION); contentValues.put(CalendarModule.EVENT_LOCATION, event.location); } - if (data.containsKey("description")) { - event.description = TiConvert.toString(data, "description"); - contentValues.put("description", event.description); + + if (data.containsKey(TiC.PROPERTY_DESCRIPTION)) { + event.description = TiConvert.toString(data, TiC.PROPERTY_DESCRIPTION); + contentValues.put(TiC.PROPERTY_DESCRIPTION, event.description); } + if (data.containsKey("begin")) { event.begin = TiConvert.toDate(data, "begin"); if (event.begin != null) { contentValues.put("dtstart", event.begin.getTime()); } } - if (data.containsKey("end")) { - event.end = TiConvert.toDate(data, "end"); + + if (data.containsKey(TiC.PROPERTY_END)) { + event.end = TiConvert.toDate(data, TiC.PROPERTY_END); if (event.end != null) { contentValues.put("dtend", event.end.getTime()); } } + if (data.containsKey("allDay")) { event.allDay = TiConvert.toBoolean(data, "allDay"); contentValues.put("allDay", event.allDay ? 1 : 0); From 8b1e4f315584a1d5088e7c21211e9ff76d45b4b9 Mon Sep 17 00:00:00 2001 From: prashantsaini1 Date: Wed, 4 Dec 2024 15:01:20 +0530 Subject: [PATCH 03/11] fix: add missing properties of `scrolling` event --- apidoc/Titanium/UI/ListView.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/apidoc/Titanium/UI/ListView.yml b/apidoc/Titanium/UI/ListView.yml index b6ac0a46f03..b2fa371f090 100644 --- a/apidoc/Titanium/UI/ListView.yml +++ b/apidoc/Titanium/UI/ListView.yml @@ -659,6 +659,30 @@ events: summary: | The expected y axis offset when the scrolling action decelerates to a stop. type: Number + + - name: visibleItemCount + summary: The number of visible items in the list view when the event fires. + type: Number + + - name: firstVisibleItem + summary: The first visible item in the list view when the event fires; this item might not be fully visible. May be -1 on iOS. + type: [Object, Number] + + - name: firstVisibleSection + summary: The first visible section in the list view when the event fires. + type: Titanium.UI.ListSection + + - name: firstVisibleItemIndex + summary: | + The index of the first visible item in the list view when the event fires; this item might not be fully visible. + Note: The index is `-1` when there are no items in the . + type: Number + + - name: firstVisibleSectionIndex + summary: | + The index of the first visible section in the list view when the event fires. + Note: The index is `-1` when there are no items in the . + type: Number properties: - name: allowsSelection From 02b1daa9d7b2b9b17a602a6acdebb04702ed152f Mon Sep 17 00:00:00 2001 From: prashantsaini1 Date: Wed, 4 Dec 2024 15:02:06 +0530 Subject: [PATCH 04/11] chore(android): add docs to new methods for Ti.Calendar.Calendar module --- apidoc/Titanium/Calendar/CalendarProxy.yml | 51 ++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/apidoc/Titanium/Calendar/CalendarProxy.yml b/apidoc/Titanium/Calendar/CalendarProxy.yml index a678efc8776..c597ccac2bd 100644 --- a/apidoc/Titanium/Calendar/CalendarProxy.yml +++ b/apidoc/Titanium/Calendar/CalendarProxy.yml @@ -17,6 +17,21 @@ methods: type: Dictionary platforms: [android, iphone, ipad, macos] + - name: createEvents + summary: Create multiple events at once in this Calendar. + description: | + Use this method to create bulk events for faster performance. + Success or failed results are returned at same positions as passed in the parameters list. + For failed events, it will be *null*, otherwise Titanium.Calendar.Event. + returns: + type: Array + parameters: + - name: propertiesArray + summary: Array of the event properties + type: Array + platforms: [android] + since: {android: "12.6.0"} + - name: getEventById summary: Gets the event with the specified identifier. returns: @@ -27,6 +42,42 @@ methods: type: String platforms: [android, iphone, ipad, macos] + - name: getEventsById + summary: Get multiple events with their specified identifier. + description: | + Use this method to fetch bulk events for faster performance. + Only successful events are returned, so the identifier of events + should be used to compare which events were not fetched successfully. + returns: + type: Array + parameters: + - name: ids + summary: Array of identifiers of events. + type: [Array,Array] + platforms: [android] + since: {android: "12.6.0"} + + - name: deleteEvents + summary: Delete multiple events with their specified identifier. + description: | + Use this method to delete bulk events for faster performance. + This method only returns the count of successfully deleted events only. + If it is important for apps to know whether the event was deleted or not, + then either [event's remove](Titanium.Calendar.Event.remove) method can be used, or + a single identifier can be passed in array of this method argument. + If a specified identifier event does not exist, it will not be treated as a count. + so count range can be in `0 <= count <= ids.length`. + returns: + name: count + type: Number + summary: Count of successfully deleted events. + parameters: + - name: ids + summary: Array of identifiers of events. + type: [Array, Array] + platforms: [android] + since: {android: "12.6.0"} + - name: getEventsBetweenDates summary: Gets events that occur between two dates. returns: From e2c4bb975ac9a2a97947870f4e6ced9dca54c8f0 Mon Sep 17 00:00:00 2001 From: prashantsaini1 Date: Wed, 4 Dec 2024 15:07:27 +0530 Subject: [PATCH 05/11] fix(android): set exitOnClose defaults to true on root window if not set already --- .../java/org/appcelerator/titanium/proxy/TiWindowProxy.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/android/titanium/src/java/org/appcelerator/titanium/proxy/TiWindowProxy.java b/android/titanium/src/java/org/appcelerator/titanium/proxy/TiWindowProxy.java index 237924bbb95..c40422a7522 100644 --- a/android/titanium/src/java/org/appcelerator/titanium/proxy/TiWindowProxy.java +++ b/android/titanium/src/java/org/appcelerator/titanium/proxy/TiWindowProxy.java @@ -568,6 +568,9 @@ protected void fillIntent(Activity activity, Intent intent) // We're opening child activity from Titanium root activity. Have it exit out of app by default. // Note: If launched via startActivityForResult(), then root activity won't be the task's root. intent.putExtra(TiC.INTENT_PROPERTY_FINISH_ROOT, true); + + // Set default value as stated in docs on first window also if not already set above. + setProperty(TiC.PROPERTY_EXIT_ON_CLOSE, true); } // Set the theme property From e67d60c3affaeca605b8e968d8f368142f2fa06e Mon Sep 17 00:00:00 2001 From: prashantsaini1 Date: Wed, 4 Dec 2024 15:20:29 +0530 Subject: [PATCH 06/11] Revert "fix(android): set exitOnClose defaults to true on root window if not set already" This reverts commit e2c4bb975ac9a2a97947870f4e6ced9dca54c8f0. --- .../java/org/appcelerator/titanium/proxy/TiWindowProxy.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/android/titanium/src/java/org/appcelerator/titanium/proxy/TiWindowProxy.java b/android/titanium/src/java/org/appcelerator/titanium/proxy/TiWindowProxy.java index c40422a7522..237924bbb95 100644 --- a/android/titanium/src/java/org/appcelerator/titanium/proxy/TiWindowProxy.java +++ b/android/titanium/src/java/org/appcelerator/titanium/proxy/TiWindowProxy.java @@ -568,9 +568,6 @@ protected void fillIntent(Activity activity, Intent intent) // We're opening child activity from Titanium root activity. Have it exit out of app by default. // Note: If launched via startActivityForResult(), then root activity won't be the task's root. intent.putExtra(TiC.INTENT_PROPERTY_FINISH_ROOT, true); - - // Set default value as stated in docs on first window also if not already set above. - setProperty(TiC.PROPERTY_EXIT_ON_CLOSE, true); } // Set the theme property From fb8ed06974b5f20bc70a14bad2c1c6a8f4284883 Mon Sep 17 00:00:00 2001 From: prashantsaini1 Date: Wed, 4 Dec 2024 15:31:50 +0530 Subject: [PATCH 07/11] fix: fix docs formatting --- apidoc/Titanium/Calendar/CalendarProxy.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apidoc/Titanium/Calendar/CalendarProxy.yml b/apidoc/Titanium/Calendar/CalendarProxy.yml index c597ccac2bd..c35fb2d98ba 100644 --- a/apidoc/Titanium/Calendar/CalendarProxy.yml +++ b/apidoc/Titanium/Calendar/CalendarProxy.yml @@ -22,13 +22,13 @@ methods: description: | Use this method to create bulk events for faster performance. Success or failed results are returned at same positions as passed in the parameters list. - For failed events, it will be *null*, otherwise Titanium.Calendar.Event. + For failed events, it will be `null`, otherwise Titanium.Calendar.Event for successful events. returns: - type: Array + type: Array parameters: - name: propertiesArray summary: Array of the event properties - type: Array + type: Array> platforms: [android] since: {android: "12.6.0"} @@ -68,7 +68,6 @@ methods: If a specified identifier event does not exist, it will not be treated as a count. so count range can be in `0 <= count <= ids.length`. returns: - name: count type: Number summary: Count of successfully deleted events. parameters: From 5dd1b1a86190c634a79220b68a6af4c9dd7baf82 Mon Sep 17 00:00:00 2001 From: Prashant Saini Date: Wed, 4 Dec 2024 18:52:32 +0530 Subject: [PATCH 08/11] Update android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java Co-authored-by: Michael Gangolf --- .../src/java/ti/modules/titanium/calendar/CalendarProxy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java b/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java index e9fc47124c0..c7074fdb4f5 100644 --- a/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java +++ b/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java @@ -230,7 +230,7 @@ public EventProxy[] createEvents(Object data) // Check for permissions. ContentResolver contentResolver = TiApplication.getInstance().getContentResolver(); - if (!CalendarProxy.hasCalendarPermissions()) { + if (!hasCalendarPermissions()) { Log.e(TAG, "Calendar permissions are missing."); return null; } From ec3fc0505f1b9598e8f5fffe69451b8066ccc144 Mon Sep 17 00:00:00 2001 From: Prashant Saini Date: Wed, 4 Dec 2024 18:52:45 +0530 Subject: [PATCH 09/11] Update android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java Co-authored-by: Michael Gangolf --- .../src/java/ti/modules/titanium/calendar/CalendarProxy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java b/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java index c7074fdb4f5..a254cb9b4e3 100644 --- a/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java +++ b/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java @@ -306,7 +306,7 @@ public int deleteEvents(Object args) // Check for permissions. ContentResolver contentResolver = TiApplication.getInstance().getContentResolver(); - if (!CalendarProxy.hasCalendarPermissions()) { + if (!hasCalendarPermissions()) { Log.e(TAG, "Calendar permissions are missing."); return deletedCount; } From d301d6edc0314745aeee6950c02c973b0b5be08a Mon Sep 17 00:00:00 2001 From: Prashant Saini Date: Wed, 4 Dec 2024 18:52:53 +0530 Subject: [PATCH 10/11] Update android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java Co-authored-by: Michael Gangolf --- .../src/java/ti/modules/titanium/calendar/CalendarProxy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java b/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java index a254cb9b4e3..dd95acc7997 100644 --- a/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java +++ b/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarProxy.java @@ -249,7 +249,7 @@ public EventProxy[] createEvents(Object data) // Necessary to keep track of non-null items later. if (contentValues == null) { eventProxies.add(null); - Log.e(TAG, "Title was not created, no title found for event"); + Log.e(TAG, "Event was not created, no title found for event"); continue; } From 569be13586807d239c6409cfde8d8d4d4a4aefda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Kn=C3=B6chel?= Date: Thu, 12 Dec 2024 14:44:40 +0100 Subject: [PATCH 11/11] fix: fix docs --- apidoc/Titanium/Calendar/CalendarProxy.yml | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/apidoc/Titanium/Calendar/CalendarProxy.yml b/apidoc/Titanium/Calendar/CalendarProxy.yml index c35fb2d98ba..a612444197f 100644 --- a/apidoc/Titanium/Calendar/CalendarProxy.yml +++ b/apidoc/Titanium/Calendar/CalendarProxy.yml @@ -18,11 +18,11 @@ methods: platforms: [android, iphone, ipad, macos] - name: createEvents - summary: Create multiple events at once in this Calendar. + summary: Creates multiple events at once in this calendar. description: | - Use this method to create bulk events for faster performance. - Success or failed results are returned at same positions as passed in the parameters list. - For failed events, it will be `null`, otherwise Titanium.Calendar.Event for successful events. + Use this method to bulk-create events for faster performance. + Successful or failed results are returned at the same position as passed in the parameters list. + For failed events, it will return `null` and for successful events. returns: type: Array parameters: @@ -43,9 +43,9 @@ methods: platforms: [android, iphone, ipad, macos] - name: getEventsById - summary: Get multiple events with their specified identifier. + summary: Gets multiple events with their specified identifier(s). description: | - Use this method to fetch bulk events for faster performance. + Use this method to bulk-fetch events for faster performance. Only successful events are returned, so the identifier of events should be used to compare which events were not fetched successfully. returns: @@ -53,20 +53,20 @@ methods: parameters: - name: ids summary: Array of identifiers of events. - type: [Array,Array] + type: [Array, Array] platforms: [android] since: {android: "12.6.0"} - name: deleteEvents - summary: Delete multiple events with their specified identifier. + summary: Deletes multiple events with their specified identifier(s). description: | - Use this method to delete bulk events for faster performance. - This method only returns the count of successfully deleted events only. + Use this method to bulk-delete events for faster performance. + This method only returns the count of successfully deleted events. If it is important for apps to know whether the event was deleted or not, - then either [event's remove](Titanium.Calendar.Event.remove) method can be used, or - a single identifier can be passed in array of this method argument. - If a specified identifier event does not exist, it will not be treated as a count. - so count range can be in `0 <= count <= ids.length`. + either use the [remove()](Titanium.Calendar.Event.remove) method, or + a single identifier that is passed as an array to this method. + If a specified identifier event does not exist, it will not be treated as a count, + so the count range can be in `0 <= count <= ids.length`. returns: type: Number summary: Count of successfully deleted events.