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

Implementing Rrule package #403

Merged
merged 23 commits into from
Oct 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
2d3a345
update to event model (Merge pull request #319 from CJohnson19/event-…
Aug 6, 2021
e3f58d0
1) Correct deprecations, 2) Change print to debugPrint globally.
Sep 5, 2021
2c6708d
1) Upgrade to Embed V2; 2) Merge pull request #311 from rmtmckenzie/f…
Oct 25, 2021
cedb832
Initial commit for working version with Rrule;
Jan 3, 2022
72d0571
iOS functioning version
GoldenSoju Jan 3, 2022
da6453f
Solved conflicts in Merging myfork/develop_rrule -> builttoroam/develop
Jan 5, 2022
13daa4b
Changes after solving merge conflicts
Jan 6, 2022
759487a
Hotfix: Add correct Rrule package fork to pubspec
Jan 6, 2022
e5d8c42
Clean up and minor corrections;
Jan 6, 2022
fe43c10
Implement newest version of the official RRULE package on Flutter and…
Jan 20, 2022
47dc314
Implement newest version of the official RRULE package on iOS;
GoldenSoju Jan 23, 2022
5bfb225
Merge branch 'develop' of github.com:builttoroam/device_calendar into…
Jan 26, 2022
2e28d00
Code base update with 'builttoroam/device_calendar'(develop) and code…
Jan 26, 2022
c968278
Merge remote-tracking branch 'MyFork/fast_merge_develop_rrule' into f…
Jan 26, 2022
26a9000
Update/Sync of Event class (event.dart).
Apr 14, 2022
0e64a98
Update/Sync of Event class from main branch (adding event status);
Jun 26, 2022
a05e980
Enabling recurring multi-(all-)day events;
Jun 28, 2022
11cb931
Bugfix for null pointer error of event status when deleting instance …
Jul 1, 2022
1003c67
Merge commit '11cb931e6596a402b955924acdc853fc0c6beb26' into develop
thomassth Oct 5, 2022
2f49382
Merge commit '1003c67dcd2b83f28c7971b5f1fbd397c3497f72' into develop
thomassth Oct 5, 2022
7dbb155
package ver sync
thomassth Oct 5, 2022
4378be0
swift eventstatus fix
thomassth Oct 5, 2022
3e8662b
Revert of merge 6029acf and commit 8cd7d14
Oct 5, 2022
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
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.google.code.gson:gson:2.8.8'
api 'androidx.appcompat:appcompat:1.3.1'
implementation 'org.dmfs:lib-recur:0.11.2'
implementation 'org.dmfs:lib-recur:0.12.2'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0'
}
3 changes: 1 addition & 2 deletions android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#Thu May 17 10:56:13 AEST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ import com.builttoroam.devicecalendar.models.Availability
import com.google.gson.*
import java.lang.reflect.Type

class AvailabilitySerializer: JsonSerializer<Availability> {
override fun serialize(src: Availability?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement {
if(src != null) {
class AvailabilitySerializer : JsonSerializer<Availability> {
override fun serialize(
src: Availability?,
typeOfSrc: Type?,
context: JsonSerializationContext?
): JsonElement {
if (src != null) {
return JsonPrimitive(src.name)
}
return JsonObject()
Expand Down

Large diffs are not rendered by default.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,70 @@ import android.app.Activity
import android.content.Context
import androidx.annotation.NonNull
import com.builttoroam.devicecalendar.common.Constants
import com.builttoroam.devicecalendar.common.DayOfWeek
import com.builttoroam.devicecalendar.common.RecurrenceFrequency
import com.builttoroam.devicecalendar.models.*
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import org.dmfs.rfc5545.recur.Freq

const val CHANNEL_NAME = "plugins.builttoroam.com/device_calendar"

class DeviceCalendarPlugin() : FlutterPlugin, MethodCallHandler, ActivityAware {
// Methods
private const val REQUEST_PERMISSIONS_METHOD = "requestPermissions"
private const val HAS_PERMISSIONS_METHOD = "hasPermissions"
private const val RETRIEVE_CALENDARS_METHOD = "retrieveCalendars"
private const val RETRIEVE_EVENTS_METHOD = "retrieveEvents"
private const val DELETE_EVENT_METHOD = "deleteEvent"
private const val DELETE_EVENT_INSTANCE_METHOD = "deleteEventInstance"
private const val CREATE_OR_UPDATE_EVENT_METHOD = "createOrUpdateEvent"
private const val CREATE_CALENDAR_METHOD = "createCalendar"
private const val DELETE_CALENDAR_METHOD = "deleteCalendar"

// Method arguments
private const val CALENDAR_ID_ARGUMENT = "calendarId"
private const val CALENDAR_NAME_ARGUMENT = "calendarName"
private const val START_DATE_ARGUMENT = "startDate"
private const val END_DATE_ARGUMENT = "endDate"
private const val EVENT_IDS_ARGUMENT = "eventIds"
private const val EVENT_ID_ARGUMENT = "eventId"
private const val EVENT_TITLE_ARGUMENT = "eventTitle"
private const val EVENT_LOCATION_ARGUMENT = "eventLocation"
private const val EVENT_URL_ARGUMENT = "eventURL"
private const val EVENT_DESCRIPTION_ARGUMENT = "eventDescription"
private const val EVENT_ALL_DAY_ARGUMENT = "eventAllDay"
private const val EVENT_START_DATE_ARGUMENT = "eventStartDate"
private const val EVENT_END_DATE_ARGUMENT = "eventEndDate"
private const val EVENT_START_TIMEZONE_ARGUMENT = "eventStartTimeZone"
private const val EVENT_END_TIMEZONE_ARGUMENT = "eventEndTimeZone"
private const val RECURRENCE_RULE_ARGUMENT = "recurrenceRule"
private const val FREQUENCY_ARGUMENT = "freq"
private const val COUNT_ARGUMENT = "count"
private const val UNTIL_ARGUMENT = "until"
private const val INTERVAL_ARGUMENT = "interval"
private const val BY_WEEK_DAYS_ARGUMENT = "byday"
private const val BY_MONTH_DAYS_ARGUMENT = "bymonthday"
private const val BY_YEAR_DAYS_ARGUMENT = "byyearday"
private const val BY_WEEKS_ARGUMENT = "byweekno"
private const val BY_MONTH_ARGUMENT = "bymonth"
private const val BY_SET_POSITION_ARGUMENT = "bysetpos"

private const val ATTENDEES_ARGUMENT = "attendees"
private const val EMAIL_ADDRESS_ARGUMENT = "emailAddress"
private const val NAME_ARGUMENT = "name"
private const val ROLE_ARGUMENT = "role"
private const val REMINDERS_ARGUMENT = "reminders"
private const val MINUTES_ARGUMENT = "minutes"
private const val FOLLOWING_INSTANCES = "followingInstances"
private const val CALENDAR_COLOR_ARGUMENT = "calendarColor"
private const val LOCAL_ACCOUNT_NAME_ARGUMENT = "localAccountName"
private const val EVENT_AVAILABILITY_ARGUMENT = "availability"
private const val ATTENDANCE_STATUS_ARGUMENT = "attendanceStatus"
private const val EVENT_STATUS_ARGUMENT = "eventStatus"

class DeviceCalendarPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {

/// The MethodChannel that will the communication between Flutter and native Android
///
Expand All @@ -27,54 +77,6 @@ class DeviceCalendarPlugin() : FlutterPlugin, MethodCallHandler, ActivityAware {
private var context: Context? = null
private var activity: Activity? = null

// Methods
private val REQUEST_PERMISSIONS_METHOD = "requestPermissions"
private val HAS_PERMISSIONS_METHOD = "hasPermissions"
private val RETRIEVE_CALENDARS_METHOD = "retrieveCalendars"
private val RETRIEVE_EVENTS_METHOD = "retrieveEvents"
private val DELETE_EVENT_METHOD = "deleteEvent"
private val DELETE_EVENT_INSTANCE_METHOD = "deleteEventInstance"
private val CREATE_OR_UPDATE_EVENT_METHOD = "createOrUpdateEvent"
private val CREATE_CALENDAR_METHOD = "createCalendar"
private val DELETE_CALENDAR_METHOD = "deleteCalendar"

// Method arguments
private val CALENDAR_ID_ARGUMENT = "calendarId"
private val CALENDAR_NAME_ARGUMENT = "calendarName"
private val START_DATE_ARGUMENT = "startDate"
private val END_DATE_ARGUMENT = "endDate"
private val EVENT_IDS_ARGUMENT = "eventIds"
private val EVENT_ID_ARGUMENT = "eventId"
private val EVENT_TITLE_ARGUMENT = "eventTitle"
private val EVENT_LOCATION_ARGUMENT = "eventLocation"
private val EVENT_URL_ARGUMENT = "eventURL"
private val EVENT_DESCRIPTION_ARGUMENT = "eventDescription"
private val EVENT_ALL_DAY_ARGUMENT = "eventAllDay"
private val EVENT_START_DATE_ARGUMENT = "eventStartDate"
private val EVENT_END_DATE_ARGUMENT = "eventEndDate"
private val EVENT_START_TIMEZONE_ARGUMENT = "eventStartTimeZone"
private val EVENT_END_TIMEZONE_ARGUMENT = "eventEndTimeZone"
private val RECURRENCE_RULE_ARGUMENT = "recurrenceRule"
private val RECURRENCE_FREQUENCY_ARGUMENT = "recurrenceFrequency"
private val TOTAL_OCCURRENCES_ARGUMENT = "totalOccurrences"
private val INTERVAL_ARGUMENT = "interval"
private val DAYS_OF_WEEK_ARGUMENT = "daysOfWeek"
private val DAY_OF_MONTH_ARGUMENT = "dayOfMonth"
private val MONTH_OF_YEAR_ARGUMENT = "monthOfYear"
private val WEEK_OF_MONTH_ARGUMENT = "weekOfMonth"
private val ATTENDEES_ARGUMENT = "attendees"
private val EMAIL_ADDRESS_ARGUMENT = "emailAddress"
private val NAME_ARGUMENT = "name"
private val ROLE_ARGUMENT = "role"
private val REMINDERS_ARGUMENT = "reminders"
private val MINUTES_ARGUMENT = "minutes"
private val FOLLOWING_INSTANCES = "followingInstances"
private val CALENDAR_COLOR_ARGUMENT = "calendarColor"
private val LOCAL_ACCOUNT_NAME_ARGUMENT = "localAccountName"
private val EVENT_AVAILABILITY_ARGUMENT = "availability"
private val ATTENDANCE_STATUS_ARGUMENT = "attendanceStatus"
private val EVENT_STATUS_ARGUMENT = "eventStatus"

private lateinit var _calendarDelegate: CalendarDelegate

override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
Expand Down Expand Up @@ -108,7 +110,7 @@ class DeviceCalendarPlugin() : FlutterPlugin, MethodCallHandler, ActivityAware {
activity = null
}

override fun onMethodCall(call: MethodCall, result: Result) {
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
REQUEST_PERMISSIONS_METHOD -> {
_calendarDelegate.requestPermissions(result)
Expand All @@ -124,13 +126,11 @@ class DeviceCalendarPlugin() : FlutterPlugin, MethodCallHandler, ActivityAware {
val startDate = call.argument<Long>(START_DATE_ARGUMENT)
val endDate = call.argument<Long>(END_DATE_ARGUMENT)
val eventIds = call.argument<List<String>>(EVENT_IDS_ARGUMENT) ?: listOf()

_calendarDelegate.retrieveEvents(calendarId!!, startDate, endDate, eventIds, result)
}
CREATE_OR_UPDATE_EVENT_METHOD -> {
val calendarId = call.argument<String>(CALENDAR_ID_ARGUMENT)
val event = parseEventArgs(call, calendarId)

_calendarDelegate.createOrUpdateEvent(calendarId!!, event, result)
}
DELETE_EVENT_METHOD -> {
Expand All @@ -146,18 +146,30 @@ class DeviceCalendarPlugin() : FlutterPlugin, MethodCallHandler, ActivityAware {
val endDate = call.argument<Long>(EVENT_END_DATE_ARGUMENT)
val followingInstances = call.argument<Boolean>(FOLLOWING_INSTANCES)

_calendarDelegate.deleteEvent(calendarId!!, eventId!!, result, startDate, endDate, followingInstances)
_calendarDelegate.deleteEvent(
calendarId!!,
eventId!!,
result,
startDate,
endDate,
followingInstances
)
}
CREATE_CALENDAR_METHOD -> {
val calendarName = call.argument<String>(CALENDAR_NAME_ARGUMENT)
val calendarColor = call.argument<String>(CALENDAR_COLOR_ARGUMENT)
val localAccountName = call.argument<String>(LOCAL_ACCOUNT_NAME_ARGUMENT)

_calendarDelegate.createCalendar(calendarName!!, calendarColor, localAccountName!!, result)
_calendarDelegate.createCalendar(
calendarName!!,
calendarColor,
localAccountName!!,
result
)
}
DELETE_CALENDAR_METHOD -> {
val calendarId = call.argument<String>(CALENDAR_ID_ARGUMENT)
_calendarDelegate.deleteCalendar(calendarId!!,result)
_calendarDelegate.deleteCalendar(calendarId!!, result)
}
else -> {
result.notImplemented()
Expand All @@ -181,78 +193,98 @@ class DeviceCalendarPlugin() : FlutterPlugin, MethodCallHandler, ActivityAware {
event.availability = parseAvailability(call.argument<String>(EVENT_AVAILABILITY_ARGUMENT))
event.eventStatus = parseEventStatus(call.argument<String>(EVENT_STATUS_ARGUMENT))

if (call.hasArgument(RECURRENCE_RULE_ARGUMENT) && call.argument<Map<String, Any>>(RECURRENCE_RULE_ARGUMENT) != null) {
if (call.hasArgument(RECURRENCE_RULE_ARGUMENT) && call.argument<Map<String, Any>>(
RECURRENCE_RULE_ARGUMENT
) != null
) {
val recurrenceRule = parseRecurrenceRuleArgs(call)
event.recurrenceRule = recurrenceRule
}

if (call.hasArgument(ATTENDEES_ARGUMENT) && call.argument<List<Map<String, Any>>>(ATTENDEES_ARGUMENT) != null) {
if (call.hasArgument(ATTENDEES_ARGUMENT) && call.argument<List<Map<String, Any>>>(
ATTENDEES_ARGUMENT
) != null
) {
event.attendees = mutableListOf()
val attendeesArgs = call.argument<List<Map<String, Any>>>(ATTENDEES_ARGUMENT)!!
for (attendeeArgs in attendeesArgs) {
event.attendees.add(Attendee(
event.attendees.add(
Attendee(
attendeeArgs[EMAIL_ADDRESS_ARGUMENT] as String,
attendeeArgs[NAME_ARGUMENT] as String?,
attendeeArgs[ROLE_ARGUMENT] as Int,
attendeeArgs[ATTENDANCE_STATUS_ARGUMENT] as Int?,
null, null))
null, null
)
)
}
}

if (call.hasArgument(REMINDERS_ARGUMENT) && call.argument<List<Map<String, Any>>>(REMINDERS_ARGUMENT) != null) {
if (call.hasArgument(REMINDERS_ARGUMENT) && call.argument<List<Map<String, Any>>>(
REMINDERS_ARGUMENT
) != null
) {
event.reminders = mutableListOf()
val remindersArgs = call.argument<List<Map<String, Any>>>(REMINDERS_ARGUMENT)!!
for (reminderArgs in remindersArgs) {
event.reminders.add(Reminder(reminderArgs[MINUTES_ARGUMENT] as Int))
}
}

return event
}

private fun parseRecurrenceRuleArgs(call: MethodCall): RecurrenceRule {
val recurrenceRuleArgs = call.argument<Map<String, Any>>(RECURRENCE_RULE_ARGUMENT)!!
val recurrenceFrequencyIndex = recurrenceRuleArgs[RECURRENCE_FREQUENCY_ARGUMENT] as Int
val recurrenceRule = RecurrenceRule(RecurrenceFrequency.values()[recurrenceFrequencyIndex])
if (recurrenceRuleArgs.containsKey(TOTAL_OCCURRENCES_ARGUMENT)) {
recurrenceRule.totalOccurrences = recurrenceRuleArgs[TOTAL_OCCURRENCES_ARGUMENT] as Int
val recurrenceFrequencyString = recurrenceRuleArgs[FREQUENCY_ARGUMENT] as String
val recurrenceFrequency = Freq.valueOf(recurrenceFrequencyString)
val recurrenceRule = RecurrenceRule(recurrenceFrequency)

if (recurrenceRuleArgs.containsKey(COUNT_ARGUMENT)) {
recurrenceRule.count = recurrenceRuleArgs[COUNT_ARGUMENT] as Int?
}

if (recurrenceRuleArgs.containsKey(INTERVAL_ARGUMENT)) {
recurrenceRule.interval = recurrenceRuleArgs[INTERVAL_ARGUMENT] as Int
}

if (recurrenceRuleArgs.containsKey(END_DATE_ARGUMENT)) {
recurrenceRule.endDate = recurrenceRuleArgs[END_DATE_ARGUMENT] as Long
if (recurrenceRuleArgs.containsKey(UNTIL_ARGUMENT)) {
recurrenceRule.until = recurrenceRuleArgs[UNTIL_ARGUMENT] as String?
}

if (recurrenceRuleArgs.containsKey(DAYS_OF_WEEK_ARGUMENT)) {
recurrenceRule.daysOfWeek = recurrenceRuleArgs[DAYS_OF_WEEK_ARGUMENT].toListOf<Int>()?.map { DayOfWeek.values()[it] }?.toMutableList()
if (recurrenceRuleArgs.containsKey(BY_WEEK_DAYS_ARGUMENT)) {
recurrenceRule.byday =
recurrenceRuleArgs[BY_WEEK_DAYS_ARGUMENT].toListOf<String>()?.toMutableList()
}

if (recurrenceRuleArgs.containsKey(DAY_OF_MONTH_ARGUMENT)) {
recurrenceRule.dayOfMonth = recurrenceRuleArgs[DAY_OF_MONTH_ARGUMENT] as Int
if (recurrenceRuleArgs.containsKey(BY_MONTH_DAYS_ARGUMENT)) {
recurrenceRule.bymonthday =
recurrenceRuleArgs[BY_MONTH_DAYS_ARGUMENT] as MutableList<Int>?
}

if (recurrenceRuleArgs.containsKey(MONTH_OF_YEAR_ARGUMENT)) {
recurrenceRule.monthOfYear = recurrenceRuleArgs[MONTH_OF_YEAR_ARGUMENT] as Int
if (recurrenceRuleArgs.containsKey(BY_YEAR_DAYS_ARGUMENT)) {
recurrenceRule.byyearday =
recurrenceRuleArgs[BY_YEAR_DAYS_ARGUMENT] as MutableList<Int>?
}

if (recurrenceRuleArgs.containsKey(WEEK_OF_MONTH_ARGUMENT)) {
recurrenceRule.weekOfMonth = recurrenceRuleArgs[WEEK_OF_MONTH_ARGUMENT] as Int
if (recurrenceRuleArgs.containsKey(BY_WEEKS_ARGUMENT)) {
recurrenceRule.byweekno = recurrenceRuleArgs[BY_WEEKS_ARGUMENT] as MutableList<Int>?
}

if (recurrenceRuleArgs.containsKey(BY_MONTH_ARGUMENT)) {
recurrenceRule.bymonth = recurrenceRuleArgs[BY_MONTH_ARGUMENT] as MutableList<Int>?
}

if (recurrenceRuleArgs.containsKey(BY_SET_POSITION_ARGUMENT)) {
recurrenceRule.bysetpos =
recurrenceRuleArgs[BY_SET_POSITION_ARGUMENT] as MutableList<Int>?
}
return recurrenceRule
}

private inline fun <reified T : Any> Any?.toListOf(): List<T>? {
return (this as List<*>?)?.filterIsInstance<T>()?.toList()
}

private inline fun <reified T : Any> Any?.toMutableListOf(): MutableList<T>? {
return this?.toListOf<T>()?.toMutableList()
}

private fun parseAvailability(value: String?): Availability? =
if (value == null || value == Constants.AVAILABILITY_UNAVAILABLE) {
null
Expand Down

This file was deleted.

Loading