diff --git a/FAQ.md b/FAQ.md index 7b08aa7349..d405bf557e 100644 --- a/FAQ.md +++ b/FAQ.md @@ -2329,7 +2329,7 @@ You can reset all questions set to not to be asked again in the three-dots overf Calendar and contact management can better be done in a separate, specialized app and is too complex to add to FairEmail, which is in itself already complex enough. -Note that FairEmail does support replying to calendar invites. +Note that FairEmail does support replying to calendar invites and adding calendar invites to your personal calendar. Please see here for some open source apps: diff --git a/app/src/main/java/eu/faircode/email/AdapterMessage.java b/app/src/main/java/eu/faircode/email/AdapterMessage.java index 60d36f7c5d..581d689610 100644 --- a/app/src/main/java/eu/faircode/email/AdapterMessage.java +++ b/app/src/main/java/eu/faircode/email/AdapterMessage.java @@ -45,6 +45,7 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.provider.CalendarContract; import android.provider.ContactsContract; import android.provider.Settings; import android.text.Editable; @@ -155,7 +156,6 @@ import biweekly.parameter.ParticipationStatus; import biweekly.property.Attendee; import biweekly.property.Method; import biweekly.property.Organizer; -import biweekly.property.Summary; import biweekly.util.ICalDate; import static android.app.Activity.RESULT_OK; @@ -328,6 +328,7 @@ public class AdapterMessage extends RecyclerView.Adapter() { + new SimpleTask() { @Override - protected File onExecute(Context context, Bundle args) throws Throwable { + protected Object onExecute(Context context, Bundle args) throws Throwable { long id = args.getLong("id"); int action = args.getInt("action"); @@ -1430,6 +1434,44 @@ public class AdapterMessage extends RecyclerView.Adapter attendee = new ArrayList<>(); + for (Attendee a : event.getAttendees()) { + String email = a.getEmail(); + if (!TextUtils.isEmpty(email)) + attendee.add(email); + } + + // https://developer.android.com/guide/topics/providers/calendar-provider.html#intent-insert + Intent intent = new Intent(Intent.ACTION_INSERT) + .setData(CalendarContract.Events.CONTENT_URI) + .putExtra(CalendarContract.Events.AVAILABILITY, CalendarContract.Events.AVAILABILITY_BUSY); + + if (summary != null) + intent.putExtra(CalendarContract.Events.TITLE, summary); + + if (start != null) + intent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, start.getTime()); + + if (end != null) + intent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end.getTime()); + + if (location != null) + intent.putExtra(CalendarContract.Events.EVENT_LOCATION, location); + + if (attendee.size() > 0) + intent.putExtra(Intent.EXTRA_EMAIL, TextUtils.join(",", attendee)); + + return intent; + } + // https://tools.ietf.org/html/rfc5546#section-4.2.2 VEvent ev = new VEvent(); ev.setOrganizer(event.getOrganizer()); @@ -1473,26 +1515,30 @@ public class AdapterMessage extends RecyclerView.Adapter + + diff --git a/app/src/main/res/layout/include_message_calendar.xml b/app/src/main/res/layout/include_message_calendar.xml index 459616429b..bb04d948db 100644 --- a/app/src/main/res/layout/include_message_calendar.xml +++ b/app/src/main/res/layout/include_message_calendar.xml @@ -108,6 +108,18 @@ app:layout_constraintStart_toEndOf="@id/btnCalendarDecline" app:layout_constraintTop_toBottomOf="@id/tvAttendees" /> + + + app:constraint_referenced_ids="btnCalendarAccept,btnCalendarDecline,btnCalendarMaybe,ibCalendar" /> \ No newline at end of file