Skip to content

Select next item after deletion and reduce code complexity #8503

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 42 additions & 27 deletions src/Files.Uwp/ViewModels/ItemViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,6 @@ public string WorkingDirectory

public event ItemLoadStatusChangedEventHandler ItemLoadStatusChanged;

public delegate void ListedItemAddedEventHandler(object sender, ListedItemAddedEventArgs e);

public event ListedItemAddedEventHandler ListedItemAdded;

public async Task SetWorkingDirectoryAsync(string value)
{
if (string.IsNullOrWhiteSpace(value))
Expand Down Expand Up @@ -432,11 +428,22 @@ private async void Connection_RequestReceived(object sender, Dictionary<string,
break;

case "Deleted":
// get the item that immediately follows matching item to be removed
// if the matching item is the last item, try to get the previous item; otherwise, null
// case must be ignored since $Recycle.Bin != $RECYCLE.BIN
var nextOfMatchingItem = filesAndFolders
.SkipWhile((x) => !x.ItemPath.Equals(itemPath, StringComparison.OrdinalIgnoreCase)).Skip(1)
.DefaultIfEmpty(filesAndFolders.TakeWhile((x) => !x.ItemPath.Equals(itemPath, StringComparison.OrdinalIgnoreCase)).LastOrDefault())
.FirstOrDefault();
var removedItem = await RemoveFileOrFolderAsync(itemPath);
if (removedItem != null)
{
await ApplySingleFileChangeAsync(removedItem);
}
if (nextOfMatchingItem != null)
{
await RequestSelectionAsync(new List<ListedItem>() { nextOfMatchingItem });
}
break;

default:
Expand Down Expand Up @@ -635,28 +642,18 @@ void UpdateUI()
}
}

private async Task NotifyListedItemAddedAsync(ListedItem addedItem)
private async Task RequestSelectionAsync(List<ListedItem> itemsToSelect)
{
// don't notify if there wasn't a listed item
if (addedItem == null)
// don't notify if there weren't listed items
if (itemsToSelect == null || itemsToSelect.IsEmpty())
{
return;
}

void NotifyUI()
{
ListedItemAdded?.Invoke(this, new ListedItemAddedEventArgs() { Item = addedItem });
}

if (NativeWinApiHelper.IsHasThreadAccessPropertyPresent && CoreApplication.MainView.DispatcherQueue.HasThreadAccess)
{
NotifyUI();
}
else
await CoreApplication.MainView.DispatcherQueue.EnqueueAsync(() =>
{
await CoreApplication.MainView.DispatcherQueue.EnqueueAsync(NotifyUI);
}

OnSelectionRequestedEvent?.Invoke(this, itemsToSelect);
});
}

private Task OrderFilesAndFoldersAsync()
Expand Down Expand Up @@ -1905,6 +1902,7 @@ private async Task ProcessOperationQueue(CancellationToken cancellationToken, bo

bool anyEdits = false;
ListedItem lastItemAdded = null;
ListedItem nextOfLastItemRemoved = null;
var rand = Guid.NewGuid();

try
Expand Down Expand Up @@ -1943,6 +1941,16 @@ private async Task ProcessOperationQueue(CancellationToken cancellationToken, bo
break;

case FILE_ACTION_REMOVED:
// get the item that immediately follows matching item to be removed
// if the matching item is the last item, try to get the previous item; otherwise, null
nextOfLastItemRemoved = filesAndFolders
.SkipWhile(x => !x.ItemPath.Equals(operation.FileName)).Skip(1)
.DefaultIfEmpty(filesAndFolders.TakeWhile(x => !x.ItemPath.Equals(operation.FileName)).LastOrDefault())
.FirstOrDefault();
await RemoveFileOrFolderAsync(operation.FileName);
anyEdits = true;
break;

case FILE_ACTION_RENAMED_OLD_NAME:
await RemoveFileOrFolderAsync(operation.FileName);
anyEdits = true;
Expand All @@ -1960,7 +1968,13 @@ private async Task ProcessOperationQueue(CancellationToken cancellationToken, bo
await ApplyFilesAndFoldersChangesAsync();
if (lastItemAdded != null)
{
await NotifyListedItemAddedAsync(lastItemAdded);
await RequestSelectionAsync(new List<ListedItem>() { lastItemAdded });
lastItemAdded = null;
}
if (nextOfLastItemRemoved != null)
{
await RequestSelectionAsync(new List<ListedItem>() { nextOfLastItemRemoved });
nextOfLastItemRemoved = null;
}
anyEdits = false;
}
Expand Down Expand Up @@ -1993,7 +2007,13 @@ private async Task ProcessOperationQueue(CancellationToken cancellationToken, bo
await ApplyFilesAndFoldersChangesAsync();
if (lastItemAdded != null)
{
await NotifyListedItemAddedAsync(lastItemAdded);
await RequestSelectionAsync(new List<ListedItem>() { lastItemAdded });
lastItemAdded = null;
}
if (nextOfLastItemRemoved != null)
{
await RequestSelectionAsync(new List<ListedItem>() { nextOfLastItemRemoved });
nextOfLastItemRemoved = null;
}
anyEdits = false;
}
Expand Down Expand Up @@ -2317,11 +2337,6 @@ public void Dispose()
}
}

public class ListedItemAddedEventArgs : EventArgs
{
public ListedItem Item { get; set; }
}

public class PageTypeUpdatedEventArgs
{
public bool IsTypeCloudDrive { get; set; }
Expand Down
16 changes: 2 additions & 14 deletions src/Files.Uwp/Views/ColumnShellPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,6 @@ private void Page_Loaded(object sender, RoutedEventArgs e)
FilesystemViewModel.DirectoryInfoUpdated += FilesystemViewModel_DirectoryInfoUpdated;
FilesystemViewModel.PageTypeUpdated += FilesystemViewModel_PageTypeUpdated;
FilesystemViewModel.OnSelectionRequestedEvent += FilesystemViewModel_OnSelectionRequestedEvent;
FilesystemViewModel.ListedItemAdded += FilesystemViewModel_ListedItemAdded;
OnNavigationParamsChanged();
this.Loaded -= Page_Loaded;
}
Expand All @@ -553,6 +552,8 @@ private void FilesystemViewModel_PageTypeUpdated(object sender, PageTypeUpdatedE

private void FilesystemViewModel_OnSelectionRequestedEvent(object sender, List<ListedItem> e)
{
// set focus since selection might occur before the UI finishes updating
ContentPage.ItemManipulationModel.FocusFileList();
ContentPage.ItemManipulationModel.SetSelectedItems(e);
}

Expand All @@ -571,18 +572,6 @@ private void FilesystemViewModel_DirectoryInfoUpdated(object sender, EventArgs e
}
}

private void FilesystemViewModel_ListedItemAdded(object sender, ListedItemAddedEventArgs e)
{
ListedItem itemToSelect = e?.Item;
if (itemToSelect != null && ContentPage != null)
{
// set focus since selection might occur before the UI finishes updating
ContentPage.ItemManipulationModel.FocusFileList();
ContentPage.ItemManipulationModel.SetSelectedItem(itemToSelect);
ContentPage.ItemManipulationModel.ScrollIntoView(itemToSelect);
}
}

private void ViewModel_WorkingDirectoryModified(object sender, WorkingDirectoryModifiedEventArgs e)
{
string value = e.Path;
Expand Down Expand Up @@ -903,7 +892,6 @@ public void Dispose()
FilesystemViewModel.DirectoryInfoUpdated -= FilesystemViewModel_DirectoryInfoUpdated;
FilesystemViewModel.PageTypeUpdated -= FilesystemViewModel_PageTypeUpdated;
FilesystemViewModel.OnSelectionRequestedEvent -= FilesystemViewModel_OnSelectionRequestedEvent;
FilesystemViewModel.ListedItemAdded -= FilesystemViewModel_ListedItemAdded;
FilesystemViewModel.Dispose();
}

Expand Down
16 changes: 2 additions & 14 deletions src/Files.Uwp/Views/ModernShellPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,6 @@ private void Page_Loaded(object sender, RoutedEventArgs e)
FilesystemViewModel.DirectoryInfoUpdated += FilesystemViewModel_DirectoryInfoUpdated;
FilesystemViewModel.PageTypeUpdated += FilesystemViewModel_PageTypeUpdated;
FilesystemViewModel.OnSelectionRequestedEvent += FilesystemViewModel_OnSelectionRequestedEvent;
FilesystemViewModel.ListedItemAdded += FilesystemViewModel_ListedItemAdded;
OnNavigationParamsChanged();
this.Loaded -= Page_Loaded;
}
Expand All @@ -596,6 +595,8 @@ private void FilesystemViewModel_PageTypeUpdated(object sender, PageTypeUpdatedE

private void FilesystemViewModel_OnSelectionRequestedEvent(object sender, List<ListedItem> e)
{
// set focus since selection might occur before the UI finishes updating
ContentPage.ItemManipulationModel.FocusFileList();
ContentPage.ItemManipulationModel.SetSelectedItems(e);
}

Expand All @@ -614,18 +615,6 @@ private void FilesystemViewModel_DirectoryInfoUpdated(object sender, EventArgs e
}
}

private void FilesystemViewModel_ListedItemAdded(object sender, ListedItemAddedEventArgs e)
{
ListedItem itemToSelect = e?.Item;
if (itemToSelect != null && ContentPage != null)
{
// set focus since selection might occur before the UI finishes updating
ContentPage.ItemManipulationModel.FocusFileList();
ContentPage.ItemManipulationModel.SetSelectedItem(itemToSelect);
ContentPage.ItemManipulationModel.ScrollIntoView(itemToSelect);
}
}

private void ViewModel_WorkingDirectoryModified(object sender, WorkingDirectoryModifiedEventArgs e)
{
if (!string.IsNullOrWhiteSpace(e.Path))
Expand Down Expand Up @@ -1010,7 +999,6 @@ public void Dispose()
FilesystemViewModel.DirectoryInfoUpdated -= FilesystemViewModel_DirectoryInfoUpdated;
FilesystemViewModel.PageTypeUpdated -= FilesystemViewModel_PageTypeUpdated;
FilesystemViewModel.OnSelectionRequestedEvent -= FilesystemViewModel_OnSelectionRequestedEvent;
FilesystemViewModel.ListedItemAdded -= FilesystemViewModel_ListedItemAdded;
FilesystemViewModel.Dispose();
}

Expand Down