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

Added event color field for Android #516

Open
wants to merge 11 commits into
base: develop
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,7 @@ class CalendarDelegate(binding: ActivityPluginBinding?, context: Context) :
values.put(Events.DTEND, end)
values.put(Events.EVENT_END_TIMEZONE, endTimeZone)
values.put(Events.DURATION, duration)
values.put(Events.EVENT_COLOR, event.eventColor)
return values
}

Expand Down Expand Up @@ -901,14 +902,17 @@ class CalendarDelegate(binding: ActivityPluginBinding?, context: Context) :
val accountName = cursor.getString(Cst.CALENDAR_PROJECTION_ACCOUNT_NAME_INDEX)
val accountType = cursor.getString(Cst.CALENDAR_PROJECTION_ACCOUNT_TYPE_INDEX)
val ownerAccount = cursor.getString(Cst.CALENDAR_PROJECTION_OWNER_ACCOUNT_INDEX)
// val name = cursor.getString(Cst.CALENDAR_PROJECTION_NAME_INDEX)


val calendar = Calendar(
calId.toString(),
displayName,
calendarColor,
accountName,
accountType,
ownerAccount
ownerAccount,
// name,
)

calendar.isReadOnly = isCalendarReadOnly(accessLevel)
Expand Down Expand Up @@ -938,6 +942,8 @@ class CalendarDelegate(binding: ActivityPluginBinding?, context: Context) :
val endTimeZone = cursor.getString(Cst.EVENT_PROJECTION_END_TIMEZONE_INDEX)
val availability = parseAvailability(cursor.getInt(Cst.EVENT_PROJECTION_AVAILABILITY_INDEX))
val eventStatus = parseEventStatus(cursor.getInt(Cst.EVENT_PROJECTION_STATUS_INDEX))
val eventColor = cursor.getLong(Cst.EVENT_PROJECTION_EVENT_COLOR_INDEX)

val event = Event()
event.eventTitle = title ?: "New Event"
event.eventId = eventId.toString()
Expand All @@ -953,6 +959,7 @@ class CalendarDelegate(binding: ActivityPluginBinding?, context: Context) :
event.eventEndTimeZone = endTimeZone
event.availability = availability
event.eventStatus = eventStatus
event.eventColor = eventColor

return event
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class Constants {
const val CALENDAR_PROJECTION_ACCESS_LEVEL_INDEX: Int = 5
const val CALENDAR_PROJECTION_COLOR_INDEX: Int = 6
const val CALENDAR_PROJECTION_IS_PRIMARY_INDEX: Int = 7
// const val CALENDAR_PROJECTION_NAME_INDEX: Int = 8


// API 17 or higher
val CALENDAR_PROJECTION: Array<String> = arrayOf(
Expand All @@ -22,8 +24,8 @@ class Constants {
CalendarContract.Calendars.OWNER_ACCOUNT, // 4
CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, // 5
CalendarContract.Calendars.CALENDAR_COLOR, // 6
CalendarContract.Calendars.IS_PRIMARY // 7

CalendarContract.Calendars.IS_PRIMARY, // 7
// CalendarContract.Calendars.NAME // 8
)

// API 16 or lower
Expand All @@ -50,6 +52,8 @@ class Constants {
const val EVENT_PROJECTION_END_TIMEZONE_INDEX: Int = 12
const val EVENT_PROJECTION_AVAILABILITY_INDEX: Int = 13
const val EVENT_PROJECTION_STATUS_INDEX: Int = 14
const val EVENT_PROJECTION_EVENT_COLOR_INDEX: Int = 15


val EVENT_PROJECTION: Array<String> = arrayOf(
CalendarContract.Instances.EVENT_ID,
Expand All @@ -66,7 +70,8 @@ class Constants {
CalendarContract.Events.EVENT_TIMEZONE,
CalendarContract.Events.EVENT_END_TIMEZONE,
CalendarContract.Events.AVAILABILITY,
CalendarContract.Events.STATUS
CalendarContract.Events.STATUS,
CalendarContract.Events.EVENT_COLOR,
)

const val EVENT_INSTANCE_DELETION_ID_INDEX: Int = 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ class Calendar(
val color: Int,
val accountName: String,
val accountType: String,
val ownerAccount: String?
val ownerAccount: String?,
// val name_: String
) {
var isReadOnly: Boolean = false
var isDefault: Boolean = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ class Event {
var reminders: MutableList<Reminder> = mutableListOf()
var availability: Availability? = null
var eventStatus: EventStatus? = null
var eventColor: Long? = null

}
25 changes: 16 additions & 9 deletions lib/src/models/calendar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,19 @@ class Calendar {
// Read-only. Account type associated with the calendar
String? accountType;

Calendar(
{this.id,
this.name,
this.isReadOnly,
this.isDefault,
this.color,
this.accountName,
this.accountType});
/// The name of this calendar (the other one up is the "display name")
// String? name_;

Calendar({
this.id,
this.name,
this.isReadOnly,
this.isDefault,
this.color,
this.accountName,
this.accountType,
// this.name_,
});

Calendar.fromJson(Map<String, dynamic> json) {
id = json['id'];
Expand All @@ -38,6 +43,7 @@ class Calendar {
color = json['color'];
accountName = json['accountName'];
accountType = json['accountType'];
// name_ = json['name_'];
}

Map<String, dynamic> toJson() {
Expand All @@ -48,7 +54,8 @@ class Calendar {
'isDefault': isDefault,
'color': color,
'accountName': accountName,
'accountType': accountType
'accountType': accountType,
// 'name_': name_
};

return data;
Expand Down
79 changes: 36 additions & 43 deletions lib/src/models/event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ class Event {
/// Indicates if this event is of confirmed, canceled, tentative or none status
EventStatus? status;

//#####
/// Read-only. Color of the event
int? color;

///Note for development:
///
///JSON field names are coded in dart, swift and kotlin to facilitate data exchange.
Expand All @@ -59,20 +63,23 @@ class Event {
///`android/src/main/kotlin/com/builttoroam/devicecalendar/models/Event.kt`
///`android/src/main/kotlin/com/builttoroam/devicecalendar/CalendarDelegate.kt`
///`android/src/main/kotlin/com/builttoroam/devicecalendar/DeviceCalendarPlugin.kt`
Event(this.calendarId,
{this.eventId,
this.title,
this.start,
this.end,
this.description,
this.attendees,
this.recurrenceRule,
this.reminders,
this.availability = Availability.Busy,
this.location,
this.url,
this.allDay = false,
this.status});
Event(
this.calendarId, {
this.eventId,
this.title,
this.start,
this.end,
this.description,
this.attendees,
this.recurrenceRule,
this.reminders,
this.availability = Availability.Busy,
this.location,
this.url,
this.allDay = false,
this.status,
this.color,
});

///Get Event from JSON.
///
Expand Down Expand Up @@ -110,22 +117,19 @@ class Event {
calendarId = json['calendarId'];
title = json['eventTitle'];
description = json['eventDescription'];
color = json['eventColor']; //#####

startTimestamp = json['eventStartDate'];
startLocationName = json['eventStartTimeZone'];
var startTimeZone = timeZoneDatabase.locations[startLocationName];
startTimeZone ??= local;
start = startTimestamp != null
? TZDateTime.fromMillisecondsSinceEpoch(startTimeZone, startTimestamp)
: TZDateTime.now(local);
start = startTimestamp != null ? TZDateTime.fromMillisecondsSinceEpoch(startTimeZone, startTimestamp) : TZDateTime.now(local);

endTimestamp = json['eventEndDate'];
endLocationName = json['eventEndTimeZone'];
var endLocation = timeZoneDatabase.locations[endLocationName];
endLocation ??= startTimeZone;
end = endTimestamp != null
? TZDateTime.fromMillisecondsSinceEpoch(endLocation, endTimestamp)
: TZDateTime.now(local);
end = endTimestamp != null ? TZDateTime.fromMillisecondsSinceEpoch(endLocation, endTimestamp) : TZDateTime.now(local);
allDay = json['eventAllDay'] ?? false;
if (Platform.isAndroid && (allDay ?? false)) {
// On Android, the datetime in an allDay event is adjusted to local
Expand Down Expand Up @@ -161,9 +165,7 @@ class Event {
// Getting and setting an organiser for iOS
var organiser = Attendee.fromJson(json['organizer']);

var attendee = attendees?.firstWhereOrNull((at) =>
at?.name == organiser.name &&
at?.emailAddress == organiser.emailAddress);
var attendee = attendees?.firstWhereOrNull((at) => at?.name == organiser.name && at?.emailAddress == organiser.emailAddress);
if (attendee != null) {
attendee.isOrganiser = true;
}
Expand All @@ -175,33 +177,27 @@ class Event {

//TODO: If we don't cast it to List<String>, the rrule package throws an error as it detects it as List<dynamic> ('Invalid JSON in 'byday'')
if (json['recurrenceRule']['byday'] != null) {
json['recurrenceRule']['byday'] =
json['recurrenceRule']['byday'].cast<String>();
json['recurrenceRule']['byday'] = json['recurrenceRule']['byday'].cast<String>();
}
//TODO: If we don't cast it to List<int>, the rrule package throws an error as it detects it as List<dynamic> ('Invalid JSON in 'bymonthday'')
if (json['recurrenceRule']['bymonthday'] != null) {
json['recurrenceRule']['bymonthday'] =
json['recurrenceRule']['bymonthday'].cast<int>();
json['recurrenceRule']['bymonthday'] = json['recurrenceRule']['bymonthday'].cast<int>();
}
//TODO: If we don't cast it to List<int>, the rrule package throws an error as it detects it as List<dynamic> ('Invalid JSON in 'byyearday'')
if (json['recurrenceRule']['byyearday'] != null) {
json['recurrenceRule']['byyearday'] =
json['recurrenceRule']['byyearday'].cast<int>();
json['recurrenceRule']['byyearday'] = json['recurrenceRule']['byyearday'].cast<int>();
}
//TODO: If we don't cast it to List<int>, the rrule package throws an error as it detects it as List<dynamic> ('Invalid JSON in 'byweekno'')
if (json['recurrenceRule']['byweekno'] != null) {
json['recurrenceRule']['byweekno'] =
json['recurrenceRule']['byweekno'].cast<int>();
json['recurrenceRule']['byweekno'] = json['recurrenceRule']['byweekno'].cast<int>();
}
//TODO: If we don't cast it to List<int>, the rrule package throws an error as it detects it as List<dynamic> ('Invalid JSON in 'bymonth'')
if (json['recurrenceRule']['bymonth'] != null) {
json['recurrenceRule']['bymonth'] =
json['recurrenceRule']['bymonth'].cast<int>();
json['recurrenceRule']['bymonth'] = json['recurrenceRule']['bymonth'].cast<int>();
}
//TODO: If we don't cast it to List<int>, the rrule package throws an error as it detects it as List<dynamic> ('Invalid JSON in 'bysetpos'')
if (json['recurrenceRule']['bysetpos'] != null) {
json['recurrenceRule']['bysetpos'] =
json['recurrenceRule']['bysetpos'].cast<int>();
json['recurrenceRule']['bysetpos'] = json['recurrenceRule']['bysetpos'].cast<int>();
}
// debugPrint("EVENT_MODEL: $title; RRULE = ${json['recurrenceRule']}");
recurrenceRule = RecurrenceRule.fromJson(json['recurrenceRule']);
Expand All @@ -214,8 +210,7 @@ class Event {
}).toList();
}
if (legacyJSON) {
throw const FormatException(
'legacy JSON detected. Please update your current JSONs as they may not be supported later on.');
throw const FormatException('legacy JSON detected. Please update your current JSONs as they may not be supported later on.');
}
}

Expand All @@ -226,25 +221,23 @@ class Event {
data['eventId'] = eventId;
data['eventTitle'] = title;
data['eventDescription'] = description;
data['eventStartDate'] = start?.millisecondsSinceEpoch ??
TZDateTime.now(local).millisecondsSinceEpoch;
data['eventStartDate'] = start?.millisecondsSinceEpoch ?? TZDateTime.now(local).millisecondsSinceEpoch;
data['eventStartTimeZone'] = start?.location.name;
data['eventEndDate'] = end?.millisecondsSinceEpoch ??
TZDateTime.now(local).millisecondsSinceEpoch;
data['eventEndDate'] = end?.millisecondsSinceEpoch ?? TZDateTime.now(local).millisecondsSinceEpoch;
data['eventEndTimeZone'] = end?.location.name;
data['eventAllDay'] = allDay;
data['eventLocation'] = location;
data['eventURL'] = url?.data?.contentText;
data['availability'] = availability.enumToString;
data['eventStatus'] = status?.enumToString;
data['eventColor'] = color; //#####

if (attendees != null) {
data['attendees'] = attendees?.map((a) => a?.toJson()).toList();
}

if (attendees != null) {
data['organizer'] =
attendees?.firstWhereOrNull((a) => a!.isOrganiser)?.toJson();
data['organizer'] = attendees?.firstWhereOrNull((a) => a!.isOrganiser)?.toJson();
}

if (recurrenceRule != null) {
Expand Down
5 changes: 2 additions & 3 deletions lib/src/models/reminder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ class Reminder {
/// The time when the reminder should be triggered expressed in terms of minutes before the start of the event
int? minutes;

Reminder({@required this.minutes})
: assert(minutes != null && minutes >= 0,
'Minutes must be greater than or equal than zero');
//2.4.24 We allow minus values for reminders, because all day event reminders on that day are set with "minus minutes" (eg. -300)
Reminder({@required this.minutes}) : assert(minutes != null, 'Minutes must not be null');

Reminder.fromJson(Map<String, dynamic> json) {
minutes = json['minutes'] as int;
Expand Down
Loading