From 1336056c9d9cfc8ac1bb4a8288f45d9242cf3b46 Mon Sep 17 00:00:00 2001 From: "Jeffrey T. Fritz" Date: Mon, 20 Mar 2023 08:49:01 -0400 Subject: [PATCH 1/3] Before stream --- sessions/Season-06/0604/README.md | 499 ++++++++++++++++++ sessions/Season-06/0604/img/EmptyView.png | Bin 0 -> 47711 bytes .../0604/img/GridItemsLayoutHorizontal.png | Bin 0 -> 420727 bytes .../0604/img/GridItemsLayoutVert.png | Bin 0 -> 788922 bytes sessions/Season-06/0604/img/PullToRefresh.PNG | Bin 0 -> 12568 bytes sessions/Season-06/0604/img/Themes.gif | Bin 0 -> 499238 bytes .../Season-06/0604/src/Directory.build.props | 9 + .../0604/src/Directory.build.targets | 10 + sessions/Season-06/0604/src/MonkeyFinder.sln | 34 ++ .../Season-06/0604/src/MonkeyFinder/App.xaml | 69 +++ .../0604/src/MonkeyFinder/App.xaml.cs | 11 + .../0604/src/MonkeyFinder/AppShell.xaml | 35 ++ .../0604/src/MonkeyFinder/AppShell.xaml.cs | 11 + .../0604/src/MonkeyFinder/GlobalUsings.cs | 9 + .../0604/src/MonkeyFinder/MauiProgram.cs | 28 + .../0604/src/MonkeyFinder/Model/Monkey.cs | 12 + .../0604/src/MonkeyFinder/MonkeyFinder.csproj | 40 ++ .../Platforms/Android/AndroidManifest.xml | 6 + .../Platforms/Android/AssemblyInfo.cs | 9 + .../Platforms/Android/MainActivity.cs | 10 + .../Platforms/Android/MainApplication.cs | 15 + .../Android/Resources/values/colors.xml | 6 + .../Platforms/MacCatalyst/AppDelegate.cs | 9 + .../Platforms/MacCatalyst/Info.plist | 32 ++ .../Platforms/MacCatalyst/Program.cs | 15 + .../MonkeyFinder/Platforms/Windows/App.xaml | 8 + .../Platforms/Windows/App.xaml.cs | 24 + .../Platforms/Windows/Package.appxmanifest | 60 +++ .../Platforms/Windows/app.manifest | 15 + .../MonkeyFinder/Platforms/iOS/AppDelegate.cs | 9 + .../src/MonkeyFinder/Platforms/iOS/Info.plist | 34 ++ .../src/MonkeyFinder/Platforms/iOS/Program.cs | 15 + .../Properties/launchSettings.json | 8 + .../Resources/Fonts/OpenSans-Regular.ttf | Bin 0 -> 106100 bytes .../Resources/Images/dotnet_bot.svg | 93 ++++ .../MonkeyFinder/Resources/Images/nodata.png | Bin 0 -> 18301 bytes .../Resources/Raw/AboutAssets.txt | 14 + .../Resources/Raw/monkeydata.json | 119 +++++ .../src/MonkeyFinder/Resources/appicon.svg | 4 + .../src/MonkeyFinder/Resources/appiconfg.svg | 8 + .../MonkeyFinder/Services/MonkeyService.cs | 34 ++ .../src/MonkeyFinder/View/DetailsPage.xaml | 52 ++ .../src/MonkeyFinder/View/DetailsPage.xaml.cs | 10 + .../0604/src/MonkeyFinder/View/MainPage.xaml | 66 +++ .../src/MonkeyFinder/View/MainPage.xaml.cs | 11 + .../MonkeyFinder/ViewModel/BaseViewModel.cs | 14 + .../ViewModel/MonkeyDetailsViewModel.cs | 11 + .../ViewModel/MonkeysViewModel.cs | 51 ++ 48 files changed, 1529 insertions(+) create mode 100644 sessions/Season-06/0604/README.md create mode 100644 sessions/Season-06/0604/img/EmptyView.png create mode 100644 sessions/Season-06/0604/img/GridItemsLayoutHorizontal.png create mode 100644 sessions/Season-06/0604/img/GridItemsLayoutVert.png create mode 100644 sessions/Season-06/0604/img/PullToRefresh.PNG create mode 100644 sessions/Season-06/0604/img/Themes.gif create mode 100644 sessions/Season-06/0604/src/Directory.build.props create mode 100644 sessions/Season-06/0604/src/Directory.build.targets create mode 100644 sessions/Season-06/0604/src/MonkeyFinder.sln create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/App.xaml create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/App.xaml.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/AppShell.xaml create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/AppShell.xaml.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/GlobalUsings.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/MauiProgram.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Model/Monkey.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/MonkeyFinder.csproj create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Platforms/Android/AndroidManifest.xml create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Platforms/Android/AssemblyInfo.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Platforms/Android/MainActivity.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Platforms/Android/MainApplication.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Platforms/Android/Resources/values/colors.xml create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Platforms/MacCatalyst/AppDelegate.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Platforms/MacCatalyst/Info.plist create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Platforms/MacCatalyst/Program.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Platforms/Windows/App.xaml create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Platforms/Windows/App.xaml.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Platforms/Windows/Package.appxmanifest create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Platforms/Windows/app.manifest create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Platforms/iOS/AppDelegate.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Platforms/iOS/Info.plist create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Platforms/iOS/Program.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Properties/launchSettings.json create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Resources/Fonts/OpenSans-Regular.ttf create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Resources/Images/dotnet_bot.svg create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Resources/Images/nodata.png create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Resources/Raw/AboutAssets.txt create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Resources/Raw/monkeydata.json create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Resources/appicon.svg create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Resources/appiconfg.svg create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/Services/MonkeyService.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/View/DetailsPage.xaml create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/View/DetailsPage.xaml.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/View/MainPage.xaml create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/View/MainPage.xaml.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/ViewModel/BaseViewModel.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/ViewModel/MonkeyDetailsViewModel.cs create mode 100644 sessions/Season-06/0604/src/MonkeyFinder/ViewModel/MonkeysViewModel.cs diff --git a/sessions/Season-06/0604/README.md b/sessions/Season-06/0604/README.md new file mode 100644 index 0000000..4123a1b --- /dev/null +++ b/sessions/Season-06/0604/README.md @@ -0,0 +1,499 @@ +## Session 0604 : Platform Features and Themes + +Our application is running on a modern operating system on a phone or desktop and should be able to access the features made available on that system. In this first part, we will access the map feature to display a monkey's location + +### Check for internet + +We can easily check to see if our user is connected to the internet with the built in `IConnectivity` of .NET MAUI + +1. First, let's get access to the `IConnectivity` found inside of .NET MAUI. Let's inject `IConnectivity` into our `MonkeysViewModel` constructor: + + ```csharp + IConnectivity connectivity; + public MonkeysViewModel(MonkeyService monkeyService, IConnectivity connectivity) + { + Title = "Monkey Finder"; + this.monkeyService = monkeyService; + this.connectivity = connectivity; + } + ``` + +1. Register the `Connectivity.Current` in our `MauiProgram.cs`. + + +1. While we are here let's add both `IGeolocation` and `IMap`, add the code: + + ```csharp + builder.Services.AddSingleton(Connectivity.Current); + builder.Services.AddSingleton(Geolocation.Default); + builder.Services.AddSingleton(Map.Default); + ``` + +1. Now, let's check for internet inside of the `GetMonkeysAsync` method and display an alert if offline. + + ```csharp + if (connectivity.NetworkAccess != NetworkAccess.Internet) + { + await Shell.Current.DisplayAlert("No connectivity!", + $"Please check internet and try again.", "OK"); + return; + } + ``` + + Run the app on your emulator and toggle on and off airplane mode to check your implementation. + + +### Find Closest Monkey! + +We can add more functionality to this page using the GPS of the device since each monkey has a latitude and longitude associated with it. + +1. First, let's get access to the `IGeolocator` found inside of .NET MAUI. Let's inject `IGeolocator` into our `MonkeysViewModel` constructor: + + ```csharp + IConnectivity connectivity; + IGeolocation geolocation; + public MonkeysViewModel(MonkeyService monkeyService, IConnectivity connectivity, IGeolocation geolocation) + { + Title = "Monkey Finder"; + this.monkeyService = monkeyService; + this.connectivity = connectivity; + this.geolocation = geolocation; + } + ``` + + +1. In our `MonkeysViewModel.cs`, let's create another method called `GetClosestMonkey`: + + ```csharp + [RelayCommand] + async Task GetClosestMonkey() + { + + } + ``` + +1. We can then fill it in by using .NET MAUI to query for our location and helpers that find the closest monkey to us: + + ```csharp + [RelayCommand] + async Task GetClosestMonkey() + { + if (IsBusy || Monkeys.Count == 0) + return; + + try + { + // Get cached location, else get real location. + var location = await geolocation.GetLastKnownLocationAsync(); + if (location == null) + { + location = await geolocation.GetLocationAsync(new GeolocationRequest + { + DesiredAccuracy = GeolocationAccuracy.Medium, + Timeout = TimeSpan.FromSeconds(30) + }); + } + + // Find closest monkey to us + var first = Monkeys.OrderBy(m => location.CalculateDistance( + new Location(m.Latitude, m.Longitude), DistanceUnits.Miles)) + .FirstOrDefault(); + + await Shell.Current.DisplayAlert("", first.Name + " " + + first.Location, "OK"); + + } + catch (Exception ex) + { + Debug.WriteLine($"Unable to query location: {ex.Message}"); + await Shell.Current.DisplayAlert("Error!", ex.Message, "OK"); + } + } + ``` + + +1. Back in our `MainPage.xaml` we can add another `Button` that will call this new method: + + Add the following XAML under the Search button. + + ```xml +