Skip to content
Draft
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BATTERY_STATS" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.INTERNET" />
Expand Down
390 changes: 390 additions & 0 deletions DeviceTests/DeviceTests.Shared/Calendar_Tests.cs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Samples/Samples.Android/Properties/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-feature android:name="android.hardware.location" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-feature android:name="android.hardware.location.network" android:required="false" />
Expand Down
32 changes: 32 additions & 0 deletions Samples/Samples/Converters/AttendeeRequiredColorConverter.cs
Original file line number Diff line number Diff line change
@@ -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();
}
}
32 changes: 32 additions & 0 deletions Samples/Samples/Converters/RecurrenceEndTypeToBoolConverter.cs
Original file line number Diff line number Diff line change
@@ -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();
}
}
}
86 changes: 86 additions & 0 deletions Samples/Samples/Converters/RecurrenceRuleTextConverter.cs
Original file line number Diff line number Diff line change
@@ -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();
}
}
32 changes: 32 additions & 0 deletions Samples/Samples/Converters/RecurrenceUntilTypeToBoolConverter.cs
Original file line number Diff line number Diff line change
@@ -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();
}
}
}
19 changes: 19 additions & 0 deletions Samples/Samples/Converters/ReminderTextConverter.cs
Original file line number Diff line number Diff line change
@@ -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();
}
}
20 changes: 20 additions & 0 deletions Samples/Samples/Converters/StartWidthDisplayConverter.cs
Original file line number Diff line number Diff line change
@@ -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();
}
}
31 changes: 31 additions & 0 deletions Samples/Samples/View/CalendarAddPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8" ?>
<views:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:Samples.View"
xmlns:viewmodels="clr-namespace:Samples.ViewModel"
xmlns:essentials="clr-namespace:Xamarin.Essentials;assembly=Xamarin.Essentials"
xmlns:converters="clr-namespace:Samples.Converters;assembly=Samples"
x:Class="Samples.View.CalendarAddPage"
x:DataType="viewmodels:CalendarAddViewModel"
Title="CalendarAddPage"
Padding="20,20,20,20">
<views:BasePage.Content>
<StackLayout>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Text="Title"
HorizontalTextAlignment="Center"
Grid.Column="0"/>
<Entry Placeholder="Title..."
Text="{Binding CalendarName}"
Grid.Column="1"/>
</Grid>
<Button Text="Add Calendar"
Command="{Binding CreateCalendar}"
IsEnabled="{Binding CanCreateCalendar}"/>
</StackLayout>
</views:BasePage.Content>
</views:BasePage>
10 changes: 10 additions & 0 deletions Samples/Samples/View/CalendarAddPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Samples.View
{
public partial class CalendarAddPage : BasePage
{
public CalendarAddPage()
{
InitializeComponent();
}
}
}
Loading