From fa1bed583758f9b6a891fc6d25481d5abcdd04a0 Mon Sep 17 00:00:00 2001 From: gal42 Date: Tue, 19 Jul 2022 10:34:42 -0700 Subject: [PATCH 01/24] MIAUI draft MIAUI sample draft for reference. Started to work on adding new task. Has bugs with InitializeComponent method --- MIAUI/MIAUI.csproj | 3 -- MIAUI/Services/IDataStore.cs | 17 +++++++ MIAUI/ViewModels/BaseViewModel.cs | 58 ++++++++++++++++++++++++ MIAUI/ViewModels/NewTaskViewModel.cs | 66 ++++++++++++++++++++++++++++ MIAUI/Views/NewTaskPage.xaml | 1 - 5 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 MIAUI/Services/IDataStore.cs create mode 100644 MIAUI/ViewModels/BaseViewModel.cs create mode 100644 MIAUI/ViewModels/NewTaskViewModel.cs diff --git a/MIAUI/MIAUI.csproj b/MIAUI/MIAUI.csproj index 8f82d8a..ccb46b8 100644 --- a/MIAUI/MIAUI.csproj +++ b/MIAUI/MIAUI.csproj @@ -57,9 +57,6 @@ - - SubtasksPage.xaml - NewTaskPage.xaml diff --git a/MIAUI/Services/IDataStore.cs b/MIAUI/Services/IDataStore.cs new file mode 100644 index 0000000..e3d86f9 --- /dev/null +++ b/MIAUI/Services/IDataStore.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MIAUI.Services +{ + public interface IDataStore + { + Task AddItemAsync(T item); + Task UpdateItemAsync(T item); + Task DeleteItemAsync(string id); + Task GetItemAsync(string id); + Task> GetItemsAsync(bool forceRefresh = false); + } +} diff --git a/MIAUI/ViewModels/BaseViewModel.cs b/MIAUI/ViewModels/BaseViewModel.cs new file mode 100644 index 0000000..3400d4b --- /dev/null +++ b/MIAUI/ViewModels/BaseViewModel.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.CompilerServices; +using Google.Apis.Util.Store; +using Microsoft.Maui.Controls; + +using MIAUI.Model; +using MIAUI.Services; +//using static Android.Content.ClipData; +using Google.Apis; + +namespace MIAUI.ViewModels +{ + public class BaseViewModel : INotifyPropertyChanged + { + public IDataStore DataStore => DependencyService.Get>(); + + bool isBusy = false; + public bool IsBusy + { + get { return isBusy; } + set { SetProperty(ref isBusy, value); } + } + + string title = string.Empty; + public string Title + { + get { return title; } + set { SetProperty(ref title, value); } + } + + protected bool SetProperty(ref T backingStore, T value, + [CallerMemberName] string propertyName = "", + Action onChanged = null) + { + if (EqualityComparer.Default.Equals(backingStore, value)) + return false; + + backingStore = value; + onChanged?.Invoke(); + OnPropertyChanged(propertyName); + return true; + } + + #region INotifyPropertyChanged + public event PropertyChangedEventHandler PropertyChanged; + protected void OnPropertyChanged([CallerMemberName] string propertyName = "") + { + var changed = PropertyChanged; + if (changed == null) + return; + + changed.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + #endregion + } +} diff --git a/MIAUI/ViewModels/NewTaskViewModel.cs b/MIAUI/ViewModels/NewTaskViewModel.cs new file mode 100644 index 0000000..67d2fc2 --- /dev/null +++ b/MIAUI/ViewModels/NewTaskViewModel.cs @@ -0,0 +1,66 @@ +using MIAUI.Model; + +namespace MIAUI.ViewModels +{ + public class NewItemViewModel : BaseViewModel + { + string _taskName; + string _subtasks; + + public NewItemViewModel() + { + SaveCommand = new Command(OnSave, ValidateSave); + CancelCommand = new Command(OnCancel); + this.PropertyChanged += + (_, __) => SaveCommand.ChangeCanExecute(); + } + + private bool ValidateSave() + { + return !String.IsNullOrWhiteSpace(_taskName ); + } + + public string TaskName + { + get => _taskName; + set => SetProperty(ref _taskName, value); + } + + public string Subtasks + { + get => _subtasks; + set => SetProperty(ref _subtasks, value); + } + + public Command SaveCommand { get; } + public Command CancelCommand { get; } + + private async void OnCancel() + { + // This will pop the current page off the navigation stack + await Shell.Current.GoToAsync(".."); + } + + private async void OnSave() + { + List subtaskList = new List (); + string[] subtaskStringList = (Subtasks ?? String.Empty).Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries); + foreach (string subtaskString in subtaskStringList) + subtaskList.Add(new Subtask { SubtaskItem = subtaskString }); + + Model.Task newItem = new () + { + //Id = Guid.NewGuid().ToString(), + TaskName = TaskName, + Subtasks = subtaskList, + }; + + await DataStore.AddItemAsync(newItem); + + SemanticScreenReader.Announce(TaskName + " task added."); + + // This will pop the current page off the navigation stack + await Shell.Current.GoToAsync(".."); + } + } +} diff --git a/MIAUI/Views/NewTaskPage.xaml b/MIAUI/Views/NewTaskPage.xaml index 45efb9b..82efca6 100644 --- a/MIAUI/Views/NewTaskPage.xaml +++ b/MIAUI/Views/NewTaskPage.xaml @@ -62,4 +62,3 @@ - From 98e6506e851f6a4d4b31b043f32899c9b21aadba Mon Sep 17 00:00:00 2001 From: gal42 Date: Tue, 26 Jul 2022 14:52:20 -0700 Subject: [PATCH 02/24] MIAUI sample that actually builds No binding has been implemented yet, but previous bugs have been fixed. --- MIAUI/ViewModels/NewTaskViewModel.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MIAUI/ViewModels/NewTaskViewModel.cs b/MIAUI/ViewModels/NewTaskViewModel.cs index 67d2fc2..9add404 100644 --- a/MIAUI/ViewModels/NewTaskViewModel.cs +++ b/MIAUI/ViewModels/NewTaskViewModel.cs @@ -1,4 +1,5 @@ using MIAUI.Model; +using System.Collections.ObjectModel; namespace MIAUI.ViewModels { @@ -9,7 +10,7 @@ public class NewItemViewModel : BaseViewModel public NewItemViewModel() { - SaveCommand = new Command(OnSave, ValidateSave); + SaveCommand = new Command(OnSave, ValidateSave); //use Async command CancelCommand = new Command(OnCancel); this.PropertyChanged += (_, __) => SaveCommand.ChangeCanExecute(); @@ -43,7 +44,7 @@ private async void OnCancel() private async void OnSave() { - List subtaskList = new List (); + ObservableCollection subtaskList = new (); string[] subtaskStringList = (Subtasks ?? String.Empty).Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (string subtaskString in subtaskStringList) subtaskList.Add(new Subtask { SubtaskItem = subtaskString }); From 6fb2fc281ae994c963636c73f8a75a8718f4c21b Mon Sep 17 00:00:00 2001 From: gal42 Date: Mon, 1 Aug 2022 10:18:03 -0700 Subject: [PATCH 03/24] Implemented LogOut feature --- .../ViewModel/ProfilePageViewModel.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/AzureADSample/AzureADSample/ViewModel/ProfilePageViewModel.cs b/AzureADSample/AzureADSample/ViewModel/ProfilePageViewModel.cs index 52ec48b..45e768a 100644 --- a/AzureADSample/AzureADSample/ViewModel/ProfilePageViewModel.cs +++ b/AzureADSample/AzureADSample/ViewModel/ProfilePageViewModel.cs @@ -1,5 +1,7 @@ using AzureADSample.Model; +using AzureADSample.Service; using CommunityToolkit.Mvvm.ComponentModel; +using Microsoft.Identity.Client; namespace AzureADSample.ViewModel; @@ -8,4 +10,16 @@ public partial class ProfilePageViewModel : ObservableObject { [ObservableProperty] User user; + async void LogOut(object sender, EventArgs e) + { + IEnumerable accounts = await AuthService.authenticationClient.GetAccountsAsync(); + + while (accounts.Any()) + { + await AuthService.authenticationClient.RemoveAsync(accounts.First()); + accounts = await AuthService.authenticationClient.GetAccountsAsync(); + } + + await Shell.Current.GoToAsync(nameof(MainPage)); + } } From df1bf7357de00e272adcb6766dca0ff8c233398e Mon Sep 17 00:00:00 2001 From: gal42 Date: Mon, 1 Aug 2022 10:21:42 -0700 Subject: [PATCH 04/24] Revert "Implemented LogOut feature" This reverts commit 05da8cd9899988c29899159e3b5eba164e6f17e9. --- .../ViewModel/ProfilePageViewModel.cs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/AzureADSample/AzureADSample/ViewModel/ProfilePageViewModel.cs b/AzureADSample/AzureADSample/ViewModel/ProfilePageViewModel.cs index 45e768a..52ec48b 100644 --- a/AzureADSample/AzureADSample/ViewModel/ProfilePageViewModel.cs +++ b/AzureADSample/AzureADSample/ViewModel/ProfilePageViewModel.cs @@ -1,7 +1,5 @@ using AzureADSample.Model; -using AzureADSample.Service; using CommunityToolkit.Mvvm.ComponentModel; -using Microsoft.Identity.Client; namespace AzureADSample.ViewModel; @@ -10,16 +8,4 @@ public partial class ProfilePageViewModel : ObservableObject { [ObservableProperty] User user; - async void LogOut(object sender, EventArgs e) - { - IEnumerable accounts = await AuthService.authenticationClient.GetAccountsAsync(); - - while (accounts.Any()) - { - await AuthService.authenticationClient.RemoveAsync(accounts.First()); - accounts = await AuthService.authenticationClient.GetAccountsAsync(); - } - - await Shell.Current.GoToAsync(nameof(MainPage)); - } } From 9f5a10a196573252f008f839feabb91e298b2266 Mon Sep 17 00:00:00 2001 From: gal42 Date: Tue, 2 Aug 2022 12:01:28 -0700 Subject: [PATCH 05/24] Added task page --- MIAUI/AppShell.xaml.cs | 4 +- MIAUI/MIAUI.csproj | 3 ++ MIAUI/ViewModels/BaseViewModel.cs | 32 +++++-------- MIAUI/ViewModels/NewTaskViewModel.cs | 67 ---------------------------- MIAUI/Views/LoginPage.xaml | 29 ++++++++++++ MIAUI/Views/LoginPage.xaml.cs | 9 ++++ 6 files changed, 56 insertions(+), 88 deletions(-) delete mode 100644 MIAUI/ViewModels/NewTaskViewModel.cs create mode 100644 MIAUI/Views/LoginPage.xaml create mode 100644 MIAUI/Views/LoginPage.xaml.cs diff --git a/MIAUI/AppShell.xaml.cs b/MIAUI/AppShell.xaml.cs index f155157..ec94be0 100644 --- a/MIAUI/AppShell.xaml.cs +++ b/MIAUI/AppShell.xaml.cs @@ -1,4 +1,6 @@ -namespace MIAUI; +using MIAUI.Views; + +namespace MIAUI; public partial class AppShell : Shell { diff --git a/MIAUI/MIAUI.csproj b/MIAUI/MIAUI.csproj index ccb46b8..8f82d8a 100644 --- a/MIAUI/MIAUI.csproj +++ b/MIAUI/MIAUI.csproj @@ -57,6 +57,9 @@ + + SubtasksPage.xaml + NewTaskPage.xaml diff --git a/MIAUI/ViewModels/BaseViewModel.cs b/MIAUI/ViewModels/BaseViewModel.cs index 3400d4b..d5fc633 100644 --- a/MIAUI/ViewModels/BaseViewModel.cs +++ b/MIAUI/ViewModels/BaseViewModel.cs @@ -9,28 +9,20 @@ using MIAUI.Services; //using static Android.Content.ClipData; using Google.Apis; +using CommunityToolkit.Mvvm.ComponentModel; +using System.Collections.ObjectModel; +using CommunityToolkit.Mvvm.Input; +using System.Threading.Tasks; +using MIAUI.Views; +using Task = System.Threading.Tasks.Task; namespace MIAUI.ViewModels { - public class BaseViewModel : INotifyPropertyChanged + public partial class BaseViewModel : ObservableObject { - public IDataStore DataStore => DependencyService.Get>(); + - bool isBusy = false; - public bool IsBusy - { - get { return isBusy; } - set { SetProperty(ref isBusy, value); } - } - - string title = string.Empty; - public string Title - { - get { return title; } - set { SetProperty(ref title, value); } - } - - protected bool SetProperty(ref T backingStore, T value, + /*protected bool SetProperty(ref T backingStore, T value, [CallerMemberName] string propertyName = "", Action onChanged = null) { @@ -41,8 +33,8 @@ protected bool SetProperty(ref T backingStore, T value, onChanged?.Invoke(); OnPropertyChanged(propertyName); return true; - } - + }*/ +/* #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = "") @@ -53,6 +45,6 @@ protected void OnPropertyChanged([CallerMemberName] string propertyName = "") changed.Invoke(this, new PropertyChangedEventArgs(propertyName)); } - #endregion + #endregion*/ } } diff --git a/MIAUI/ViewModels/NewTaskViewModel.cs b/MIAUI/ViewModels/NewTaskViewModel.cs deleted file mode 100644 index 9add404..0000000 --- a/MIAUI/ViewModels/NewTaskViewModel.cs +++ /dev/null @@ -1,67 +0,0 @@ -using MIAUI.Model; -using System.Collections.ObjectModel; - -namespace MIAUI.ViewModels -{ - public class NewItemViewModel : BaseViewModel - { - string _taskName; - string _subtasks; - - public NewItemViewModel() - { - SaveCommand = new Command(OnSave, ValidateSave); //use Async command - CancelCommand = new Command(OnCancel); - this.PropertyChanged += - (_, __) => SaveCommand.ChangeCanExecute(); - } - - private bool ValidateSave() - { - return !String.IsNullOrWhiteSpace(_taskName ); - } - - public string TaskName - { - get => _taskName; - set => SetProperty(ref _taskName, value); - } - - public string Subtasks - { - get => _subtasks; - set => SetProperty(ref _subtasks, value); - } - - public Command SaveCommand { get; } - public Command CancelCommand { get; } - - private async void OnCancel() - { - // This will pop the current page off the navigation stack - await Shell.Current.GoToAsync(".."); - } - - private async void OnSave() - { - ObservableCollection subtaskList = new (); - string[] subtaskStringList = (Subtasks ?? String.Empty).Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries); - foreach (string subtaskString in subtaskStringList) - subtaskList.Add(new Subtask { SubtaskItem = subtaskString }); - - Model.Task newItem = new () - { - //Id = Guid.NewGuid().ToString(), - TaskName = TaskName, - Subtasks = subtaskList, - }; - - await DataStore.AddItemAsync(newItem); - - SemanticScreenReader.Announce(TaskName + " task added."); - - // This will pop the current page off the navigation stack - await Shell.Current.GoToAsync(".."); - } - } -} diff --git a/MIAUI/Views/LoginPage.xaml b/MIAUI/Views/LoginPage.xaml new file mode 100644 index 0000000..b3be2db --- /dev/null +++ b/MIAUI/Views/LoginPage.xaml @@ -0,0 +1,29 @@ + + + +