diff --git a/DeviceTests/DeviceTests.Android/Properties/AndroidManifest.xml b/DeviceTests/DeviceTests.Android/Properties/AndroidManifest.xml index 8c38e08a0..61b1737c9 100644 --- a/DeviceTests/DeviceTests.Android/Properties/AndroidManifest.xml +++ b/DeviceTests/DeviceTests.Android/Properties/AndroidManifest.xml @@ -5,7 +5,8 @@ - + + diff --git a/DeviceTests/DeviceTests.Shared/Calendar_Tests.cs b/DeviceTests/DeviceTests.Shared/Calendar_Tests.cs index c60511927..54671ca8d 100644 --- a/DeviceTests/DeviceTests.Shared/Calendar_Tests.cs +++ b/DeviceTests/DeviceTests.Shared/Calendar_Tests.cs @@ -1,4 +1,7 @@ using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Xamarin.Essentials; using Xunit; @@ -99,5 +102,392 @@ public Task Get_Event_By_Bad_Text_Id(string eventId) await Assert.ThrowsAsync(() => Calendars.GetEventAsync(eventId)); }); } + + [Fact] + public Task Full_Calendar_Edit_Test() + { + return Utils.OnMainThread(async () => + { + // Create Calendar + var calendars = await Calendars.GetCalendarsAsync(); + var calendar = calendars.FirstOrDefault(x => x.Name == "Test_Calendar"); + var calendarId = string.Empty; + if (calendar == null) + { + var newCalendar = new Calendar() { Name = "Test_Calendar" }; + calendarId = await Calendars.CreateCalendar(newCalendar); + } + else + { + calendarId = calendar.Id; + } + + var startDate = TimeZoneInfo.ConvertTime(new DateTimeOffset(2019, 4, 1, 10, 30, 0, TimeZoneInfo.Local.BaseUtcOffset), TimeZoneInfo.Local); + var events = await Calendars.GetEventsAsync(calendarId, startDate, startDate.AddHours(10)); + var newEvent = events.FirstOrDefault(x => x.Title == "Test_Event"); + var eventId = string.Empty; + if (newEvent == null) + { + newEvent = new CalendarEvent() + { + Title = "Test_Event", + CalendarId = calendarId, + StartDate = startDate, + EndDate = startDate.AddHours(10) + }; + eventId = await Calendars.CreateCalendarEvent(newEvent); + } + else + { + eventId = newEvent.Id; + } + Assert.NotEmpty(eventId); + var createdEvent = await Calendars.GetEventByIdAsync(eventId); + newEvent.Id = createdEvent.Id; + newEvent.Attendees = createdEvent.Attendees; + + Assert.Equal(newEvent.Id, createdEvent.Id); + Assert.Equal(newEvent.CalendarId, createdEvent.CalendarId); + Assert.Equal(newEvent.Title, createdEvent.Title); + Assert.Equal(string.Empty, createdEvent.Description); + Assert.Equal(string.Empty, createdEvent.Location); + Assert.Equal(string.Empty, createdEvent.Url); + Assert.Equal(newEvent.AllDay, createdEvent.AllDay); + Assert.Equal(newEvent.StartDate, createdEvent.StartDate); + Assert.Equal(newEvent.Duration, createdEvent.Duration); + Assert.Equal(newEvent.EndDate, createdEvent.EndDate); + Assert.Equal(newEvent.Attendees, createdEvent.Attendees); + Assert.Equal(newEvent.Reminders, createdEvent.Reminders); + Assert.Equal(newEvent.RecurrancePattern, createdEvent.RecurrancePattern); + + createdEvent.RecurrancePattern = new RecurrenceRule() + { + Frequency = RecurrenceFrequency.YearlyOnDay, + Interval = 1, + WeekOfMonth = IterationOffset.Second, + DaysOfTheWeek = new List() { CalendarDayOfWeek.Thursday }, + MonthOfTheYear = MonthOfYear.April, + TotalOccurrences = 4 + }; + createdEvent.AllDay = true; + + var updateSuccessful = await Calendars.UpdateCalendarEvent(createdEvent); + var updatedEvent = await Calendars.GetEventByIdAsync(createdEvent.Id); + + // Updated Successfuly + Assert.True(updateSuccessful); + Assert.Equal(createdEvent.Id, updatedEvent.Id); + Assert.Equal(createdEvent.CalendarId, updatedEvent.CalendarId); + Assert.Equal(createdEvent.Title, updatedEvent.Title); + Assert.Equal(createdEvent.Description, updatedEvent.Description); + Assert.Equal(createdEvent.Location, updatedEvent.Location); + Assert.Equal(createdEvent.Url, updatedEvent.Url); + Assert.Equal(createdEvent.AllDay, updatedEvent.AllDay); + Assert.NotEqual(createdEvent.StartDate, updatedEvent.StartDate); + Assert.Equal(createdEvent.Attendees, updatedEvent.Attendees); + Assert.Equal(createdEvent.Reminders, updatedEvent.Reminders); + + var attendeeToAddAndRemove = new CalendarEventAttendee() { Email = "fake@email.com", Name = "Fake Email", Type = AttendeeType.Resource }; + + // Added Attendee to event successfully + var attendeeAddedSuccessfully = await Calendars.AddAttendeeToEvent(attendeeToAddAndRemove, updatedEvent.Id); + Assert.True(attendeeAddedSuccessfully); + + // Verify Attendee added to event + updatedEvent = await Calendars.GetEventByIdAsync(createdEvent.Id); + var expectedAttendeeCount = createdEvent.Attendees != null ? createdEvent.Attendees.Count() + 1 : 1; + Assert.Equal(updatedEvent.Attendees.Count(), expectedAttendeeCount); + + // Remove Attendee from event + var removedAttendeeSuccessfully = await Calendars.RemoveAttendeeFromEvent(attendeeToAddAndRemove, updatedEvent.Id); + Assert.True(removedAttendeeSuccessfully); + + var dateOfSecondOccurence = TimeZoneInfo.ConvertTime(new DateTimeOffset(2020, 4, 9, 0, 0, 0, TimeZoneInfo.Local.BaseUtcOffset), TimeZoneInfo.Local); + var eventInstance = await Calendars.GetEventInstanceByIdAsync(updatedEvent.Id, dateOfSecondOccurence); + + // Retrieve instance of event + Assert.Equal(eventInstance.Id, updatedEvent.Id); + Assert.Equal(eventInstance.StartDate.Date, dateOfSecondOccurence.Date); + + // Delete instance of event + var canDeleteInstance = await Calendars.DeleteCalendarEventInstanceByDate(eventInstance.Id, calendarId, eventInstance.StartDate); + Assert.True(canDeleteInstance); + + // Get whole event + var eventStillExists = await Calendars.GetEventByIdAsync(eventInstance.Id); + Assert.NotNull(eventStillExists); + + // Delete whole event + var deleteEvent = await Calendars.DeleteCalendarEventById(eventInstance.Id, calendarId); + Assert.True(deleteEvent); + }); + } + + [Fact] + public Task Basic_Calendar_Creation() + { + return Utils.OnMainThread(async () => + { + var newCalendar = new Calendar() { Name = "Test_Calendar" }; + var calendarId = await Calendars.CreateCalendar(newCalendar); + Assert.NotEmpty(calendarId); + }); + } + + [Fact] + public Task Basic_Calendar_Event_Creation() + { + return Utils.OnMainThread(async () => + { + var calendars = await Calendars.GetCalendarsAsync(); + var calendar = calendars.FirstOrDefault(x => x.Name == "Test_Calendar"); + var calendarId = string.Empty; + if (calendar == null) + { + var newCalendar = new Calendar() { Name = "Test_Calendar" }; + calendarId = await Calendars.CreateCalendar(newCalendar); + } + else + { + calendarId = calendar.Id; + } + + var startDate = TimeZoneInfo.ConvertTime(new DateTimeOffset(2019, 4, 1, 10, 30, 0, TimeZoneInfo.Local.BaseUtcOffset), TimeZoneInfo.Local); + var newEvent = new CalendarEvent() + { + Title = "Test_Event", + CalendarId = calendarId, + StartDate = startDate, + EndDate = startDate.AddHours(10) + }; + var eventId = await Calendars.CreateCalendarEvent(newEvent); + Assert.NotEmpty(eventId); + }); + } + + [Fact] + public Task Basic_Calendar_Event_Attendee_Add() + { + return Utils.OnMainThread(async () => + { + var calendars = await Calendars.GetCalendarsAsync(); + var calendar = calendars.FirstOrDefault(x => x.Name == "Test_Calendar"); + var calendarId = string.Empty; + if (calendar == null) + { + var newCalendar = new Calendar() { Name = "Test_Calendar" }; + calendarId = await Calendars.CreateCalendar(newCalendar); + } + else + { + calendarId = calendar.Id; + } + + var startDate = TimeZoneInfo.ConvertTime(new DateTimeOffset(2019, 4, 1, 10, 30, 0, TimeZoneInfo.Local.BaseUtcOffset), TimeZoneInfo.Local); + var events = await Calendars.GetEventsAsync(calendarId, startDate, startDate.AddHours(10)); + var newEvent = events.FirstOrDefault(x => x.Title == "Test_Event"); + var eventId = string.Empty; + if (newEvent == null) + { + newEvent = new CalendarEvent() + { + Title = "Test_Event", + CalendarId = calendarId, + StartDate = startDate, + EndDate = startDate.AddHours(10) + }; + eventId = await Calendars.CreateCalendarEvent(newEvent); + } + else + { + eventId = newEvent.Id; + } + var attendeeToAdd = new CalendarEventAttendee() { Email = "fake@email.com", Name = "Fake Out", Type = AttendeeType.Required }; + Assert.True(await Calendars.AddAttendeeToEvent(attendeeToAdd, eventId)); + + newEvent = await Calendars.GetEventByIdAsync(eventId); + var attendee = newEvent.Attendees.FirstOrDefault(x => x.Email == "fake@email.com"); + + Assert.Equal(attendee.Email, attendeeToAdd.Email); + Assert.Equal(attendee.Name, attendeeToAdd.Name); + Assert.Equal(attendee.IsOrganizer, attendeeToAdd.IsOrganizer); + Assert.Equal(attendee.Type, attendeeToAdd.Type); + }); + } + + [Fact] + public Task Basic_Calendar_Event_Attendee_Remove() + { + return Utils.OnMainThread(async () => + { + var calendars = await Calendars.GetCalendarsAsync(); + var calendar = calendars.FirstOrDefault(x => x.Name == "Test_Calendar"); + var calendarId = string.Empty; + if (calendar == null) + { + var newCalendar = new Calendar() { Name = "Test_Calendar" }; + calendarId = await Calendars.CreateCalendar(newCalendar); + } + else + { + calendarId = calendar.Id; + } + + var startDate = TimeZoneInfo.ConvertTime(new DateTimeOffset(2019, 4, 1, 10, 30, 0, TimeZoneInfo.Local.BaseUtcOffset), TimeZoneInfo.Local); + var events = await Calendars.GetEventsAsync(calendarId, startDate, startDate.AddHours(10)); + var newEvent = events.FirstOrDefault(x => x.Title == "Test_Event"); + var eventId = string.Empty; + if (newEvent == null) + { + newEvent = new CalendarEvent() + { + Title = "Test_Event", + CalendarId = calendarId, + StartDate = startDate, + EndDate = startDate.AddHours(10) + }; + eventId = await Calendars.CreateCalendarEvent(newEvent); + } + else + { + eventId = newEvent.Id; + } + + var attendeeCount = 0; + CalendarEventAttendee attendeeToAdd = null; + CalendarEventAttendee attendee = null; + if (newEvent.Attendees != null) + { + if (newEvent.Attendees.Count() > 0) + { + attendeeToAdd = newEvent.Attendees.FirstOrDefault(x => x.Email == "fake@email.com"); + if (attendeeToAdd != null) + { + attendeeCount = newEvent.Attendees.Count(); + attendee = attendeeToAdd; + } + else + { + attendeeToAdd = new CalendarEventAttendee() { Email = "fake@email.com", Name = "Fake Out", Type = AttendeeType.Required }; + Assert.True(await Calendars.AddAttendeeToEvent(attendeeToAdd, eventId)); + newEvent = await Calendars.GetEventByIdAsync(eventId); + attendeeCount = newEvent.Attendees.Count(); + attendee = newEvent.Attendees.FirstOrDefault(x => x.Email == "fake@email.com"); + + Assert.Equal(attendee.Email, attendeeToAdd.Email); + Assert.Equal(attendee.Name, attendeeToAdd.Name); + Assert.Equal(attendee.IsOrganizer, attendeeToAdd.IsOrganizer); + Assert.Equal(attendee.Type, attendeeToAdd.Type); + } + } + } + else + { + attendeeToAdd = new CalendarEventAttendee() { Email = "fake@email.com", Name = "Fake Out", Type = AttendeeType.Required }; + Assert.True(await Calendars.AddAttendeeToEvent(attendeeToAdd, eventId)); + newEvent = await Calendars.GetEventByIdAsync(eventId); + attendeeCount = newEvent.Attendees.Count(); + attendee = newEvent.Attendees.FirstOrDefault(x => x.Email == "fake@email.com"); + + Assert.Equal(attendee.Email, attendeeToAdd.Email); + Assert.Equal(attendee.Name, attendeeToAdd.Name); + Assert.Equal(attendee.IsOrganizer, attendeeToAdd.IsOrganizer); + Assert.Equal(attendee.Type, attendeeToAdd.Type); + } + Assert.True(await Calendars.RemoveAttendeeFromEvent(attendee, eventId)); + newEvent = await Calendars.GetEventByIdAsync(eventId); + var newAttendeeCount = newEvent.Attendees.Count(); + + Assert.Equal(attendeeCount - 1, newAttendeeCount); + }); + } + + [Fact] + public Task Basic_Calendar_Event_Update() + { + return Utils.OnMainThread(async () => + { + var calendars = await Calendars.GetCalendarsAsync(); + var calendar = calendars.FirstOrDefault(x => x.Name == "Test_Calendar"); + var calendarId = string.Empty; + if (calendar == null) + { + var newCalendar = new Calendar() { Name = "Test_Calendar" }; + calendarId = await Calendars.CreateCalendar(newCalendar); + } + else + { + calendarId = calendar.Id; + } + + var startDate = TimeZoneInfo.ConvertTime(new DateTimeOffset(2019, 4, 1, 10, 30, 0, TimeZoneInfo.Local.BaseUtcOffset), TimeZoneInfo.Local); + var events = await Calendars.GetEventsAsync(calendarId, startDate, startDate.AddHours(10)); + var newEvent = events.FirstOrDefault(x => x.Title == "Test_Event"); + if (newEvent == null) + { + newEvent = new CalendarEvent() + { + Title = "Test_Event", + CalendarId = calendarId, + StartDate = startDate, + EndDate = startDate.AddHours(10) + }; + var eventId = await Calendars.CreateCalendarEvent(newEvent); + newEvent = await Calendars.GetEventByIdAsync(eventId); + } + else + { + newEvent = await Calendars.GetEventByIdAsync(newEvent.Id); + } + + newEvent.AllDay = true; + + var result = await Calendars.UpdateCalendarEvent(newEvent); + Assert.True(result); + }); + } + + [Fact] + public Task Basic_Calendar_Event_Deletion() + { + return Utils.OnMainThread(async () => + { + var calendars = await Calendars.GetCalendarsAsync(); + var calendar = calendars.FirstOrDefault(x => x.Name == "Test_Calendar"); + var calendarId = string.Empty; + if (calendar == null) + { + var newCalendar = new Calendar() { Name = "Test_Calendar" }; + calendarId = await Calendars.CreateCalendar(newCalendar); + } + else + { + calendarId = calendar.Id; + } + + var startDate = TimeZoneInfo.ConvertTime(new DateTimeOffset(2019, 4, 1, 10, 30, 0, TimeZoneInfo.Local.BaseUtcOffset), TimeZoneInfo.Local); + var events = await Calendars.GetEventsAsync(calendarId, startDate, startDate.AddHours(10)); + var newEvent = events.FirstOrDefault(x => x.Title == "Test_Event"); + var eventId = string.Empty; + if (newEvent == null) + { + newEvent = new CalendarEvent() + { + Title = "Test_Event", + CalendarId = calendarId, + StartDate = startDate, + EndDate = startDate.AddHours(10) + }; + eventId = await Calendars.CreateCalendarEvent(newEvent); + } + else + { + eventId = newEvent.Id; + } + var result = await Calendars.DeleteCalendarEventById(eventId, calendarId); + + Assert.True(result); + }); + } } } diff --git a/Samples/Samples.Android/Properties/AndroidManifest.xml b/Samples/Samples.Android/Properties/AndroidManifest.xml index b5127354e..9966edeff 100644 --- a/Samples/Samples.Android/Properties/AndroidManifest.xml +++ b/Samples/Samples.Android/Properties/AndroidManifest.xml @@ -12,7 +12,7 @@ - + diff --git a/Samples/Samples/Converters/AttendeeRequiredColorConverter.cs b/Samples/Samples/Converters/AttendeeRequiredColorConverter.cs new file mode 100644 index 000000000..2031479b8 --- /dev/null +++ b/Samples/Samples/Converters/AttendeeRequiredColorConverter.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using Xamarin.Essentials; +using Xamarin.Forms; + +namespace Samples.Converters +{ + public class AttendeeRequiredColorConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (!(value is AttendeeType attendeeType)) + { + return Color.PaleVioletRed; + } + + switch (attendeeType) + { + case AttendeeType.Required: + return Color.LightGoldenrodYellow; + case AttendeeType.Resource: + return Color.PaleGreen; + default: + return Color.LightGray; + } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException(); + } +} diff --git a/Samples/Samples/Converters/RecurrenceDayToBoolConverter.cs b/Samples/Samples/Converters/RecurrenceDayToBoolConverter.cs new file mode 100644 index 000000000..8e53f2548 --- /dev/null +++ b/Samples/Samples/Converters/RecurrenceDayToBoolConverter.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.ObjectModel; +using System.Globalization; +using System.Linq; +using Samples.ViewModel; +using Xamarin.Essentials; +using Xamarin.Forms; + +namespace Samples.Converters +{ + public class RecurrenceDayToBoolConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null || !(value is CalendarDayOfWeek recurrenceDays) || !(parameter is CalendarDayOfWeek expectedResult)) + { + return false; + } + + return recurrenceDays == expectedResult; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null || !(value is bool switchValue) || !(parameter is CalendarDayOfWeek expectedResult) || switchValue == false) + { + return null; + } + + return expectedResult; + } + } +} diff --git a/Samples/Samples/Converters/RecurrenceEndTypeToBoolConverter.cs b/Samples/Samples/Converters/RecurrenceEndTypeToBoolConverter.cs new file mode 100644 index 000000000..abb1611e3 --- /dev/null +++ b/Samples/Samples/Converters/RecurrenceEndTypeToBoolConverter.cs @@ -0,0 +1,32 @@ +using System; +using System.Globalization; +using Samples.ViewModel; +using Xamarin.Forms; + +namespace Samples.Converters +{ + public class RecurrenceEndTypeToBoolConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null || !(value is string type)) + { + return false; + } + switch (type) + { + case RecurrenceEndType.AfterOccurences: + return true; + case RecurrenceEndType.UntilEndDate: + case RecurrenceEndType.Indefinitely: + default: + return false; + } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Samples/Samples/Converters/RecurrenceRuleTextConverter.cs b/Samples/Samples/Converters/RecurrenceRuleTextConverter.cs new file mode 100644 index 000000000..140069843 --- /dev/null +++ b/Samples/Samples/Converters/RecurrenceRuleTextConverter.cs @@ -0,0 +1,86 @@ +using System; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using Xamarin.Essentials; +using Xamarin.Forms; + +namespace Samples.Converters +{ + public class RecurrenceRuleTextConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null || !(value is RecurrenceRule rule)) + return null; + + var toReturn = $"Occurs "; + + if (rule.Interval > 0) + { + if (rule.Interval == 1) + { + toReturn += $"Every "; + } + else + { + toReturn += $"Every {((int)rule.Interval).ToOrdinal()} "; + } + switch (rule.Frequency) + { + case RecurrenceFrequency.Daily: + toReturn += "Day "; + break; + case RecurrenceFrequency.Weekly: + toReturn += "Week "; + break; + case RecurrenceFrequency.Monthly: + case RecurrenceFrequency.MonthlyOnDay: + toReturn += "Month "; + break; + case RecurrenceFrequency.Yearly: + case RecurrenceFrequency.YearlyOnDay: + toReturn += "Year "; + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + if (rule.WeekOfMonth != null && (rule.Frequency == RecurrenceFrequency.MonthlyOnDay || rule.Frequency == RecurrenceFrequency.YearlyOnDay)) + { + toReturn += $"on the {rule.WeekOfMonth} "; + if (rule.DaysOfTheWeek?.Count > 0) + { + toReturn += $"["; + toReturn = rule.DaysOfTheWeek.Aggregate(toReturn, (current, d) => current + $"{d}, "); + toReturn = toReturn.Substring(0, toReturn.Length - 2) + "] "; + } + if (rule.Frequency == RecurrenceFrequency.YearlyOnDay) + { + toReturn += $"in {rule.MonthOfTheYear.ToString()} "; + } + } + else if (rule.DaysOfTheWeek?.Count > 0) + { + toReturn += $"On: ["; + toReturn = rule.DaysOfTheWeek.Aggregate(toReturn, (current, d) => current + $"{d}, "); + toReturn = toReturn.Substring(0, toReturn.Length - 2) + "] "; + } + + if (rule.TotalOccurrences > 0) + { + toReturn += $"For the next {rule.TotalOccurrences} occurrences "; + } + + if (rule.EndDate.HasValue) + { + toReturn += $"Until {rule.EndDate.Value.DateTime.ToShortDateString()} "; + } + + return toReturn; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException(); + } +} diff --git a/Samples/Samples/Converters/RecurrenceTypeToBoolConverter.cs b/Samples/Samples/Converters/RecurrenceTypeToBoolConverter.cs new file mode 100644 index 000000000..04350fe96 --- /dev/null +++ b/Samples/Samples/Converters/RecurrenceTypeToBoolConverter.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.ObjectModel; +using System.Globalization; +using System.Linq; +using Samples.ViewModel; +using Xamarin.Essentials; +using Xamarin.Forms; + +namespace Samples.Converters +{ + public class RecurrenceTypeToBoolConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null || !(value is RecurrenceFrequency recurrenceType) || !(parameter is RecurrenceFrequency expectedResult)) + { + return false; + } + + switch (expectedResult) + { + case RecurrenceFrequency.Monthly: + return recurrenceType == RecurrenceFrequency.MonthlyOnDay || + recurrenceType == RecurrenceFrequency.Monthly || + recurrenceType == RecurrenceFrequency.YearlyOnDay || + recurrenceType == RecurrenceFrequency.Yearly; + case RecurrenceFrequency.Yearly: + return recurrenceType == RecurrenceFrequency.Yearly || + recurrenceType == RecurrenceFrequency.YearlyOnDay; + default: + return recurrenceType == expectedResult; + } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null || !(value is bool switchValue) || !(parameter is RecurrenceFrequency expectedResult) || switchValue == false) + { + return false; + } + + return expectedResult; + } + } +} diff --git a/Samples/Samples/Converters/RecurrenceUntilTypeToBoolConverter.cs b/Samples/Samples/Converters/RecurrenceUntilTypeToBoolConverter.cs new file mode 100644 index 000000000..acb1fff4b --- /dev/null +++ b/Samples/Samples/Converters/RecurrenceUntilTypeToBoolConverter.cs @@ -0,0 +1,32 @@ +using System; +using System.Globalization; +using Samples.ViewModel; +using Xamarin.Forms; + +namespace Samples.Converters +{ + public class RecurrenceUntilTypeToBoolConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null || !(value is string type)) + { + return false; + } + switch (type) + { + case RecurrenceEndType.UntilEndDate: + return true; + case RecurrenceEndType.Indefinitely: + case RecurrenceEndType.AfterOccurences: + default: + return false; + } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Samples/Samples/Converters/ReminderTextConverter.cs b/Samples/Samples/Converters/ReminderTextConverter.cs new file mode 100644 index 000000000..57b7cb0c5 --- /dev/null +++ b/Samples/Samples/Converters/ReminderTextConverter.cs @@ -0,0 +1,19 @@ +using System; +using System.Globalization; +using Xamarin.Forms; + +namespace Samples.Converters +{ + public class ReminderTextConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null || !(value is int minutes)) + return null; + + return minutes > 0 ? $"{minutes} minutes prior" : "No Reminders"; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException(); + } +} diff --git a/Samples/Samples/Converters/StartWidthDisplayConverter.cs b/Samples/Samples/Converters/StartWidthDisplayConverter.cs new file mode 100644 index 000000000..1c2f3a92e --- /dev/null +++ b/Samples/Samples/Converters/StartWidthDisplayConverter.cs @@ -0,0 +1,20 @@ +using System; +using System.Globalization; +using Xamarin.Forms; + +namespace Samples.Converters +{ + public class StartWidthDisplayConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null || !(value is bool b)) + { + return 1; + } + return b ? 3 : 1; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException(); + } +} diff --git a/Samples/Samples/View/CalendarAddPage.xaml b/Samples/Samples/View/CalendarAddPage.xaml new file mode 100644 index 000000000..0fab192ce --- /dev/null +++ b/Samples/Samples/View/CalendarAddPage.xaml @@ -0,0 +1,31 @@ + + + + + + + + + + +