Skip to content

Commit 86a9037

Browse files
🧱 Mason: [structural improvement] (#308)
* Move DragItemsCompleted logic to ViewModels using x:Bind * Remove dead code and add test for PersistFolderSequence --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
1 parent b3068cc commit 86a9037

7 files changed

Lines changed: 46 additions & 38 deletions

File tree

Launchbox.Tests/SettingsViewModelTests.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ public async Task Dispose_WhileToggleInFlight_DoesNotThrow()
352352
}
353353

354354
[Fact]
355-
public void SetFolderSequence_ReordersAndRefreshesFolders()
355+
public void PersistFolderSequence_ReordersAndRefreshesFolders()
356356
{
357357
var store = new MockSettingsStore();
358358
var folders = new System.Collections.Generic.List<ShortcutFolder>
@@ -368,11 +368,19 @@ public void SetFolderSequence_ReordersAndRefreshesFolders()
368368
new ShortcutFolderManager(store));
369369
var vm = new SettingsViewModel(settingsService, new MockWindowService(), new MockFilePickerService(), new MockDispatcher());
370370

371-
vm.SetFolderSequence([@"C:\Desktop\B", @"C:\Desktop\A"]);
371+
// Simulate ListView reordering the underlying collection directly
372+
var folderA = vm.Folders[0];
373+
var folderB = vm.Folders[1];
374+
vm.Folders.Clear();
375+
vm.Folders.Add(folderB);
376+
vm.Folders.Add(folderA);
372377

373-
Assert.Equal(2, vm.Folders.Count);
374-
Assert.Equal("B", vm.Folders[0].Label);
375-
Assert.Equal("A", vm.Folders[1].Label);
378+
vm.PersistFolderSequence();
379+
380+
var updatedFolders = settingsService.GetShortcutFolders();
381+
Assert.Equal(2, updatedFolders.Count);
382+
Assert.Equal("B", updatedFolders[0].Label);
383+
Assert.Equal("A", updatedFolders[1].Label);
376384
}
377385

378386
[Fact]

MainWindow.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@
143143
CanReorderItems="{x:Bind ViewModel.IsFilterEmpty, Mode=OneWay}"
144144
AllowDrop="{x:Bind ViewModel.IsFilterEmpty, Mode=OneWay}"
145145
CanDragItems="{x:Bind ViewModel.IsFilterEmpty, Mode=OneWay}"
146-
DragItemsCompleted="AppGrid_DragItemsCompleted"
146+
DragItemsCompleted="{x:Bind ViewModel.PersistItemOrder}"
147147
ItemTemplate="{StaticResource AppItemTemplate}">
148148
</GridView>
149149

MainWindow.xaml.cs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -264,17 +264,4 @@ private void Grid_CharacterReceived(UIElement sender, CharacterReceivedRoutedEve
264264
args.Handled = true;
265265
}
266266

267-
private void AppGrid_DragItemsCompleted(ListViewBase sender, DragItemsCompletedEventArgs args)
268-
{
269-
// FilteredApps is already in the new order — WinUI modified it in-place during drag.
270-
// Persist the new order so it survives app restarts.
271-
try
272-
{
273-
ViewModel.PersistItemOrder();
274-
}
275-
catch (Exception ex)
276-
{
277-
Trace.WriteLine($"Failed to persist item order: {PathSecurity.GetSafeExceptionMessage(ex)}");
278-
}
279-
}
280267
}

SettingsWindow.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
CanReorderItems="True"
4343
AllowDrop="True"
4444
CanDragItems="True"
45-
DragItemsCompleted="FolderList_DragItemsCompleted">
45+
DragItemsCompleted="{x:Bind ViewModel.PersistFolderSequence}">
4646
<ListView.ItemTemplate>
4747
<DataTemplate x:DataType="models:ShortcutFolder">
4848
<Grid ColumnDefinitions="*,Auto,Auto,Auto,Auto" Padding="4" ColumnSpacing="4">

SettingsWindow.xaml.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,4 @@ private void SettingsWindow_Closed(object sender, WindowEventArgs args)
4848
ViewModel.Dispose();
4949
}
5050

51-
private void FolderList_DragItemsCompleted(ListViewBase sender, DragItemsCompletedEventArgs args)
52-
{
53-
var orderedPaths = sender.Items.OfType<ShortcutFolder>().Select(f => f.Path).ToList();
54-
ViewModel.SetFolderSequence(orderedPaths);
55-
}
5651
}

ViewModels/MainViewModel.cs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -538,18 +538,25 @@ private void ToggleGroup(AppItemGroup? group)
538538
/// </summary>
539539
public void PersistItemOrder()
540540
{
541-
var orders = FilteredApps
542-
.GroupBy(a => a.FolderPath)
543-
.ToDictionary(g => g.Key, g => g.Select(a => Path.GetFileName(a.Path)).ToList());
544-
// Merge rather than replace: a folder that is currently unavailable (e.g. slow drive
545-
// that failed to load) produces no items in FilteredApps and must not lose its saved order.
546-
_settingsService.MergeItemOrders(orders);
547-
548-
// Sync Apps without triggering a redundant RebuildFilteredApps — FilteredApps == Apps
549-
// when no filter is active (CanReorderItems is bound to IsFilterEmpty).
550-
Apps.CollectionChanged -= Apps_CollectionChanged;
551-
Apps.ReplaceAll(FilteredApps);
552-
Apps.CollectionChanged += Apps_CollectionChanged;
541+
try
542+
{
543+
var orders = FilteredApps
544+
.GroupBy(a => a.FolderPath)
545+
.ToDictionary(g => g.Key, g => g.Select(a => Path.GetFileName(a.Path)).ToList());
546+
// Merge rather than replace: a folder that is currently unavailable (e.g. slow drive
547+
// that failed to load) produces no items in FilteredApps and must not lose its saved order.
548+
_settingsService.MergeItemOrders(orders);
549+
550+
// Sync Apps without triggering a redundant RebuildFilteredApps — FilteredApps == Apps
551+
// when no filter is active (CanReorderItems is bound to IsFilterEmpty).
552+
Apps.CollectionChanged -= Apps_CollectionChanged;
553+
Apps.ReplaceAll(FilteredApps);
554+
Apps.CollectionChanged += Apps_CollectionChanged;
555+
}
556+
catch (Exception ex)
557+
{
558+
Trace.WriteLine($"Failed to persist item order: {PathSecurity.GetSafeExceptionMessage(ex)}");
559+
}
553560
}
554561

555562
private void RebuildFolderWatchers(IReadOnlyList<ShortcutFolder> folders)

ViewModels/SettingsViewModel.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,18 @@ private async Task RenameFolderAsync(ShortcutFolder folder)
150150

151151
private void ApplyRename(int order, string newLabel) => _settingsService.RenameShortcutFolder(order, newLabel);
152152

153-
public void SetFolderSequence(IReadOnlyList<string> orderedPaths) => _settingsService.SetShortcutFolderSequence(orderedPaths);
153+
public void PersistFolderSequence()
154+
{
155+
try
156+
{
157+
var orderedPaths = Folders.Select(f => f.Path).ToList();
158+
_settingsService.SetShortcutFolderSequence(orderedPaths);
159+
}
160+
catch (Exception ex)
161+
{
162+
Trace.WriteLine($"Failed to persist folder sequence: {PathSecurity.GetSafeExceptionMessage(ex)}");
163+
}
164+
}
154165

155166
private void RefreshFolders()
156167
{

0 commit comments

Comments
 (0)