From 5f55a43f713de5f51941e0337cbeefb4063878d3 Mon Sep 17 00:00:00 2001 From: Phil Seeman Date: Mon, 7 Jul 2025 22:14:03 -0400 Subject: [PATCH 1/2] Some additional code cleanup --- demos/MAUITodo/Data/NodeConnector.cs | 11 ++---- demos/MAUITodo/Data/PowerSyncData.cs | 10 +++--- demos/MAUITodo/Models/TodoItem.cs | 10 +++--- demos/MAUITodo/Views/ListsPage.xaml.cs | 22 ++++++------ demos/MAUITodo/Views/TodoListPage.xaml.cs | 44 +++++++++++------------ 5 files changed, 47 insertions(+), 50 deletions(-) diff --git a/demos/MAUITodo/Data/NodeConnector.cs b/demos/MAUITodo/Data/NodeConnector.cs index 2f8f4aa..cc2df51 100644 --- a/demos/MAUITodo/Data/NodeConnector.cs +++ b/demos/MAUITodo/Data/NodeConnector.cs @@ -1,16 +1,11 @@ -using PowerSync.Common.Client; +using System.Text; +using System.Text.Json; +using PowerSync.Common.Client; using PowerSync.Common.Client.Connection; using PowerSync.Common.DB.Crud; namespace MAUITodo.Data; -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Text; -using System.Text.Json; -using System.Threading.Tasks; - public class NodeConnector : IPowerSyncBackendConnector { private string StorageFilePath => Path.Combine(FileSystem.AppDataDirectory, "user_id.txt"); diff --git a/demos/MAUITodo/Data/PowerSyncData.cs b/demos/MAUITodo/Data/PowerSyncData.cs index dde1fd0..f71db05 100644 --- a/demos/MAUITodo/Data/PowerSyncData.cs +++ b/demos/MAUITodo/Data/PowerSyncData.cs @@ -62,6 +62,7 @@ public async Task DeleteListAsync(TodoList list) await Db.Execute("DELETE FROM todos WHERE list_id = ?", [listId]); await Db.Execute("DELETE FROM lists WHERE id = ?", [listId]); } + public async Task SaveItemAsync(TodoItem item) { if (item.ID != "") @@ -74,7 +75,7 @@ await Db.Execute( item.Description, item.Completed ? 1 : 0, item.CompletedAt!, - UserId, + item.Completed ? UserId : null, item.ID ]); } @@ -82,14 +83,15 @@ await Db.Execute( { await Db.Execute( @"INSERT INTO todos - (id, list_id, description, created_at, completed, created_by, completed_at) - VALUES (uuid(), ?, ?, datetime(), ?, ?, ?)", + (id, list_id, description, created_at, created_by, completed, completed_at, completed_by) + VALUES (uuid(), ?, ?, datetime(), ?, ?, ?, ?)", [ item.ListId, item.Description, - item.Completed ? 1 : 0, UserId, + item.Completed ? 1 : 0, item.CompletedAt!, + item.Completed ? UserId : null ]); } } diff --git a/demos/MAUITodo/Models/TodoItem.cs b/demos/MAUITodo/Models/TodoItem.cs index a482ac3..d15a1c7 100644 --- a/demos/MAUITodo/Models/TodoItem.cs +++ b/demos/MAUITodo/Models/TodoItem.cs @@ -11,20 +11,20 @@ public class TodoItem public string ListId { get; set; } = null!; [JsonProperty("created_at")] - public string CreatedAt { get; set; }= null!; + public string CreatedAt { get; set; } = null!; [JsonProperty("completed_at")] public string? CompletedAt { get; set; } [JsonProperty("description")] - public string Description { get; set; }= null!; + public string Description { get; set; } = null!; [JsonProperty("created_by")] - public string CreatedBy { get; set; }= null!; + public string CreatedBy { get; set; } = null!; [JsonProperty("completed_by")] - public string CompletedBy { get; set; }= null!; + public string CompletedBy { get; set; } = null!; [JsonProperty("completed")] - public bool Completed { get; set; } = false; + public bool Completed { get; set; } } diff --git a/demos/MAUITodo/Views/ListsPage.xaml.cs b/demos/MAUITodo/Views/ListsPage.xaml.cs index 2a436a9..a4df8d3 100644 --- a/demos/MAUITodo/Views/ListsPage.xaml.cs +++ b/demos/MAUITodo/Views/ListsPage.xaml.cs @@ -4,7 +4,7 @@ namespace MAUITodo.Views; -public partial class ListsPage : ContentPage +public partial class ListsPage { private readonly PowerSyncData database; @@ -46,7 +46,7 @@ protected override async void OnAppearing() private async void OnAddClicked(object sender, EventArgs e) { - string name = await DisplayPromptAsync("New List", "Enter list name:"); + var name = await DisplayPromptAsync("New List", "Enter list name:"); if (!string.IsNullOrWhiteSpace(name)) { var list = new TodoList { Name = name }; @@ -56,16 +56,16 @@ private async void OnAddClicked(object sender, EventArgs e) private async void OnDeleteClicked(object sender, EventArgs e) { - var button = (Button)sender; - var list = (TodoList)button.CommandParameter; - - bool confirm = await DisplayAlert("Confirm Delete", - $"Are you sure you want to delete the list '{list.Name}'?", - "Yes", "No"); - - if (confirm) + if (sender is Button button && button.CommandParameter is TodoList list) { - await database.DeleteListAsync(list); + var confirm = await DisplayAlert("Confirm Delete", + $"Are you sure you want to delete the list '{list.Name}'?", + "Yes", "No"); + + if (confirm) + { + await database.DeleteListAsync(list); + } } } diff --git a/demos/MAUITodo/Views/TodoListPage.xaml.cs b/demos/MAUITodo/Views/TodoListPage.xaml.cs index 8887405..dcb6b19 100644 --- a/demos/MAUITodo/Views/TodoListPage.xaml.cs +++ b/demos/MAUITodo/Views/TodoListPage.xaml.cs @@ -4,7 +4,7 @@ namespace MAUITodo.Views; -public partial class TodoListPage : ContentPage +public partial class TodoListPage { private readonly PowerSyncData database; private readonly TodoList selectedList; @@ -38,11 +38,11 @@ protected override async void OnAppearing() private async void OnAddClicked(object sender, EventArgs e) { - string description = await DisplayPromptAsync("New Todo", "Enter todo description:"); + var description = await DisplayPromptAsync("New Todo", "Enter todo description:"); if (!string.IsNullOrWhiteSpace(description)) { - var todo = new TodoItem - { + var todo = new TodoItem + { Description = description, ListId = selectedList.ID }; @@ -52,30 +52,30 @@ private async void OnAddClicked(object sender, EventArgs e) private async void OnDeleteClicked(object sender, EventArgs e) { - var button = (Button)sender; - var todo = (TodoItem)button.CommandParameter; - - bool confirm = await DisplayAlert("Confirm Delete", - $"Are you sure you want to delete '{todo.Description}'?", - "Yes", "No"); - - if (confirm) + if (sender is Button button && button.CommandParameter is TodoItem todo) { - await database.DeleteItemAsync(todo); + var confirm = await DisplayAlert("Confirm Delete", + $"Are you sure you want to delete '{todo.Description}'?", + "Yes", "No"); + + if (confirm) + { + await database.DeleteItemAsync(todo); + } } } private async void OnCheckBoxChanged(object sender, CheckedChangedEventArgs e) { - if (sender is CheckBox checkBox && - checkBox.Parent?.Parent?.BindingContext is TodoItem todo) + if (sender is CheckBox checkBox && checkBox.Parent?.Parent?.BindingContext is TodoItem todo) { - if (e.Value == true && todo.CompletedAt == null) + if (e.Value && todo.CompletedAt == null) { todo.Completed = e.Value; - todo.CompletedAt = DateTime.UtcNow.ToString("o"); + todo.CompletedAt = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss"); await database.SaveItemAsync(todo); - } else if (e.Value == false && todo.CompletedAt != null) + } + else if (e.Value == false && todo.CompletedAt != null) { todo.Completed = e.Value; todo.CompletedAt = null; // Uncheck, clear completed time @@ -88,16 +88,16 @@ private async void OnItemSelected(object sender, SelectionChangedEventArgs e) { if (e.CurrentSelection.FirstOrDefault() is TodoItem selectedItem) { - string newDescription = await DisplayPromptAsync("Edit Todo", - "Enter new description:", + var newDescription = await DisplayPromptAsync("Edit Todo", + "Enter new description:", initialValue: selectedItem.Description); - + if (!string.IsNullOrWhiteSpace(newDescription)) { selectedItem.Description = newDescription; await database.SaveItemAsync(selectedItem); } - + TodoItemsCollection.SelectedItem = null; } } From e0c0dba337efd585967b720e80325be512c596ea Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Tue, 29 Jul 2025 13:57:38 +0200 Subject: [PATCH 2/2] Added dedicated SaveTodoCompleted method. --- demos/MAUITodo/Data/PowerSyncData.cs | 31 ++++++++++++++++++++--- demos/MAUITodo/Views/TodoListPage.xaml.cs | 10 +++----- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/demos/MAUITodo/Data/PowerSyncData.cs b/demos/MAUITodo/Data/PowerSyncData.cs index f71db05..21c381c 100644 --- a/demos/MAUITodo/Data/PowerSyncData.cs +++ b/demos/MAUITodo/Data/PowerSyncData.cs @@ -35,10 +35,10 @@ public PowerSyncData() var nodeConnector = new NodeConnector(); UserId = nodeConnector.UserId; - + Db.Connect(nodeConnector); } - + public async Task SaveListAsync(TodoList list) { if (list.ID != "") @@ -62,7 +62,7 @@ public async Task DeleteListAsync(TodoList list) await Db.Execute("DELETE FROM todos WHERE list_id = ?", [listId]); await Db.Execute("DELETE FROM lists WHERE id = ?", [listId]); } - + public async Task SaveItemAsync(TodoItem item) { if (item.ID != "") @@ -96,6 +96,31 @@ await Db.Execute( } } + public async Task SaveTodoCompletedAsync(string todoId, bool completed) + { + if (completed) + { + await Db.Execute( + @"UPDATE todos + SET completed = 1, completed_at = datetime(), completed_by = ? + WHERE id = ?", + [ + UserId, + todoId + ]); + } + else + { + await Db.Execute( + @"UPDATE todos + SET completed = 0, completed_at = NULL, completed_by = NULL + WHERE id = ?", + [ + todoId + ]); + } + } + public async Task DeleteItemAsync(TodoItem item) { await Db.Execute("DELETE FROM todos WHERE id = ?", [item.ID]); diff --git a/demos/MAUITodo/Views/TodoListPage.xaml.cs b/demos/MAUITodo/Views/TodoListPage.xaml.cs index dcb6b19..a46a639 100644 --- a/demos/MAUITodo/Views/TodoListPage.xaml.cs +++ b/demos/MAUITodo/Views/TodoListPage.xaml.cs @@ -18,11 +18,11 @@ public TodoListPage(PowerSyncData powerSyncData, TodoList list) } public string ListName => selectedList?.Name ?? ""; - + protected override async void OnAppearing() { base.OnAppearing(); - + await database.Db.Watch("select * from todos where list_id = ?", [selectedList.ID], new WatchHandler { OnResult = (results) => @@ -72,14 +72,12 @@ private async void OnCheckBoxChanged(object sender, CheckedChangedEventArgs e) if (e.Value && todo.CompletedAt == null) { todo.Completed = e.Value; - todo.CompletedAt = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss"); - await database.SaveItemAsync(todo); + await database.SaveTodoCompletedAsync(todo.ID, true); } else if (e.Value == false && todo.CompletedAt != null) { todo.Completed = e.Value; - todo.CompletedAt = null; // Uncheck, clear completed time - await database.SaveItemAsync(todo); + await database.SaveTodoCompletedAsync(todo.ID, false); } } }