Skip to content

Commit a7f97f9

Browse files
lukeblevinsyaira2
andauthored
Codebase Quality: Network drives service and view model (#12176)
Co-authored-by: Yair <39923744+yaira2@users.noreply.github.com>
1 parent 5810235 commit a7f97f9

File tree

9 files changed

+203
-165
lines changed

9 files changed

+203
-165
lines changed

src/Files.App/App.xaml.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ public partial class App : Application
6363
public static RecentItems RecentItemsManager { get; private set; }
6464
public static QuickAccessManager QuickAccessManager { get; private set; }
6565
public static CloudDrivesManager CloudDrivesManager { get; private set; }
66-
public static NetworkDrivesManager NetworkDrivesManager { get; private set; }
6766
public static WSLDistroManager WSLDistroManager { get; private set; }
6867
public static LibraryManager LibraryManager { get; private set; }
6968
public static FileTagsManager FileTagsManager { get; private set; }
@@ -74,8 +73,6 @@ public partial class App : Application
7473
public static string AppVersion = $"{Package.Current.Id.Version.Major}.{Package.Current.Id.Version.Minor}.{Package.Current.Id.Version.Build}.{Package.Current.Id.Version.Revision}";
7574
public static string LogoPath;
7675

77-
public IServiceProvider Services { get; private set; }
78-
7976
/// <summary>
8077
/// Initializes the singleton application object. This is the first line of authored code
8178
/// executed, and as such is the logical equivalent of main() or WinMain().
@@ -94,7 +91,6 @@ private static void EnsureSettingsAndConfigurationAreBootstrapped()
9491
RecentItemsManager ??= new RecentItems();
9592
AppModel ??= new AppModel();
9693
LibraryManager ??= new LibraryManager();
97-
NetworkDrivesManager ??= new NetworkDrivesManager();
9894
CloudDrivesManager ??= new CloudDrivesManager();
9995
WSLDistroManager ??= new WSLDistroManager();
10096
FileTagsManager ??= new FileTagsManager();
@@ -131,7 +127,6 @@ await Task.WhenAll(
131127
StartAppCenter(),
132128
OptionalTask(CloudDrivesManager.UpdateDrivesAsync(), generalSettingsService.ShowCloudDrivesSection),
133129
LibraryManager.UpdateLibrariesAsync(),
134-
OptionalTask(NetworkDrivesManager.UpdateDrivesAsync(), generalSettingsService.ShowNetworkDrivesSection),
135130
OptionalTask(WSLDistroManager.UpdateDrivesAsync(), generalSettingsService.ShowWslSection),
136131
OptionalTask(FileTagsManager.UpdateFileTagsAsync(), generalSettingsService.ShowFileTagsSection),
137132
QuickAccessManager.InitializeAsync()
@@ -225,11 +220,13 @@ protected override void OnLaunched(LaunchActivatedEventArgs e)
225220
.AddSingleton<IResourcesService, ResourcesService>()
226221
.AddSingleton<IJumpListService, JumpListService>()
227222
.AddSingleton<IRemovableDrivesService, RemovableDrivesService>()
223+
.AddSingleton<INetworkDrivesService, NetworkDrivesService>()
228224
.AddSingleton<MainPageViewModel>()
229225
.AddSingleton<PreviewPaneViewModel>()
230226
.AddSingleton<SidebarViewModel>()
231227
.AddSingleton<SettingsViewModel>()
232228
.AddSingleton<DrivesViewModel>()
229+
.AddSingleton<NetworkDrivesViewModel>()
233230
.AddSingleton<OngoingTasksViewModel>()
234231
.AddSingleton<AppearanceViewModel>()
235232
)

src/Files.App/Filesystem/NetworkDrivesManager.cs

Lines changed: 0 additions & 130 deletions
This file was deleted.

src/Files.App/Filesystem/StorageFileHelpers/StorageFileExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,9 @@ private static PathBoxItem GetPathItem(string component, string path)
292292
else if (component.Contains(':', StringComparison.Ordinal))
293293
{
294294
var drivesViewModel = Ioc.Default.GetRequiredService<DrivesViewModel>();
295+
var networkDrivesViewModel = Ioc.Default.GetRequiredService<NetworkDrivesViewModel>();
295296

296-
var drives = drivesViewModel.Drives.Cast<DriveItem>().Concat(App.NetworkDrivesManager.Drives).Concat(App.CloudDrivesManager.Drives);
297+
var drives = drivesViewModel.Drives.Concat(networkDrivesViewModel.Drives).Cast<DriveItem>().Concat(App.CloudDrivesManager.Drives);
297298
var drive = drives.FirstOrDefault(y => y.ItemType is NavigationControlItemType.Drive && y.Path.Contains(component, StringComparison.OrdinalIgnoreCase));
298299
title = drive is not null ? drive.Text : $@"Drive ({component})";
299300
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright (c) 2023 Files Community
2+
// Licensed under the MIT License. See the LICENSE.
3+
4+
using Files.App.DataModels.NavigationControlItems;
5+
using Files.App.Shell;
6+
using Files.Backend.Services;
7+
using Files.Sdk.Storage.LocatableStorage;
8+
using Vanara.PInvoke;
9+
using Vanara.Windows.Shell;
10+
11+
namespace Files.App.ServicesImplementation
12+
{
13+
public class NetworkDrivesService : INetworkDrivesService
14+
{
15+
public bool DisconnectNetworkDrive(ILocatableFolder drive)
16+
{
17+
return NetworkDrivesAPI.DisconnectNetworkDrive(drive.Path);
18+
}
19+
20+
public async IAsyncEnumerable<ILocatableFolder> GetDrivesAsync()
21+
{
22+
var networkLocations = await Win32API.StartSTATask(() =>
23+
{
24+
var locations = new List<ShellLinkItem>();
25+
using (var nethood = new ShellFolder(Shell32.KNOWNFOLDERID.FOLDERID_NetHood))
26+
{
27+
foreach (var item in nethood)
28+
{
29+
if (item is ShellLink link)
30+
{
31+
locations.Add(ShellFolderExtensions.GetShellLinkItem(link));
32+
}
33+
else
34+
{
35+
var linkPath = (string)item.Properties["System.Link.TargetParsingPath"];
36+
if (linkPath is not null)
37+
{
38+
var linkItem = ShellFolderExtensions.GetShellFileItem(item);
39+
locations.Add(new ShellLinkItem(linkItem) { TargetPath = linkPath });
40+
}
41+
}
42+
}
43+
}
44+
return locations;
45+
});
46+
47+
foreach (var item in networkLocations ?? Enumerable.Empty<ShellLinkItem>())
48+
{
49+
var networkItem = new DriveItem
50+
{
51+
Text = System.IO.Path.GetFileNameWithoutExtension(item.FileName),
52+
Path = item.TargetPath,
53+
DeviceID = item.FilePath,
54+
Type = DriveType.Network,
55+
ItemType = NavigationControlItemType.Drive,
56+
};
57+
networkItem.MenuOptions = new ContextMenuOptions
58+
{
59+
IsLocationItem = true,
60+
ShowEjectDevice = networkItem.IsRemovable,
61+
ShowShellItems = true,
62+
ShowProperties = true,
63+
};
64+
65+
yield return networkItem;
66+
}
67+
}
68+
69+
public Task OpenMapNetworkDriveDialogAsync()
70+
{
71+
var handle = NativeWinApiHelper.CoreWindowHandle.ToInt64();
72+
return NetworkDrivesAPI.OpenMapNetworkDriveDialog(handle);
73+
}
74+
}
75+
}

src/Files.App/UserControls/Widgets/DrivesWidget.xaml.cs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,14 @@
55
using CommunityToolkit.Mvvm.Input;
66
using CommunityToolkit.WinUI;
77
using Files.App.DataModels.NavigationControlItems;
8-
using Files.App.Extensions;
9-
using Files.App.Filesystem;
10-
using Files.App.Helpers;
118
using Files.App.Shell;
12-
using Files.App.ViewModels;
139
using Files.App.ViewModels.Widgets;
14-
using Files.Backend.Services.Settings;
15-
using Files.Shared.Extensions;
1610
using Microsoft.UI.Xaml;
1711
using Microsoft.UI.Xaml.Controls;
1812
using Microsoft.UI.Xaml.Input;
1913
using Microsoft.UI.Xaml.Media.Imaging;
20-
using System;
21-
using System.Collections.Generic;
22-
using System.Collections.ObjectModel;
2314
using System.Collections.Specialized;
24-
using System.ComponentModel;
25-
using System.Linq;
2615
using System.Runtime.CompilerServices;
27-
using System.Threading.Tasks;
2816
using System.Windows.Input;
2917
using Windows.System;
3018
using Windows.UI.Core;
@@ -74,7 +62,7 @@ public sealed partial class DrivesWidget : HomePageWidget, IWidgetItemModel, INo
7462
{
7563
public IUserSettingsService userSettingsService { get; } = Ioc.Default.GetRequiredService<IUserSettingsService>();
7664
private DrivesViewModel drivesViewModel = Ioc.Default.GetRequiredService<DrivesViewModel>();
77-
65+
private NetworkDrivesViewModel networkDrivesViewModel = Ioc.Default.GetRequiredService<NetworkDrivesViewModel>();
7866
public delegate void DrivesWidgetInvokedEventHandler(object sender, DrivesWidgetInvokedEventArgs e);
7967

8068
public event DrivesWidgetInvokedEventHandler DrivesWidgetInvoked;
@@ -143,7 +131,7 @@ public DrivesWidget()
143131
OpenPropertiesCommand = new RelayCommand<DriveCardItem>(OpenProperties);
144132
PinToFavoritesCommand = new AsyncRelayCommand<WidgetCardItem>(PinToFavorites);
145133
UnpinFromFavoritesCommand = new AsyncRelayCommand<WidgetCardItem>(UnpinFromFavorites);
146-
MapNetworkDriveCommand = new AsyncRelayCommand(DoNetworkMapDrive);
134+
MapNetworkDriveCommand = new AsyncRelayCommand(DoNetworkMapDriveAsync);
147135
DisconnectNetworkDriveCommand = new RelayCommand<DriveCardItem>(DisconnectNetworkDrive);
148136
}
149137

@@ -268,9 +256,9 @@ public override List<ContextMenuFlyoutItemViewModel> GetItemMenuItems(WidgetCard
268256
}.Where(x => x.ShowItem).ToList();
269257
}
270258

271-
private async Task DoNetworkMapDrive()
259+
private Task DoNetworkMapDriveAsync()
272260
{
273-
await NetworkDrivesManager.OpenMapNetworkDriveDialogAsync(NativeWinApiHelper.CoreWindowHandle.ToInt64());
261+
return networkDrivesViewModel.OpenMapNetworkDriveDialogAsync();
274262
}
275263

276264
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
@@ -357,7 +345,7 @@ private void MenuFlyout_Opening(object sender, object e)
357345

358346
private void DisconnectNetworkDrive(DriveCardItem item)
359347
{
360-
NetworkDrivesManager.DisconnectNetworkDrive(item.Item.Path);
348+
networkDrivesViewModel.DisconnectNetworkDrive(item.Item);
361349
}
362350

363351
private void GoToStorageSense_Click(object sender, RoutedEventArgs e)

src/Files.App/ViewModels/MainPageViewModel.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class MainPageViewModel : ObservableObject
1818
private IUserSettingsService userSettingsService;
1919
private IAppearanceSettingsService appearanceSettingsService;
2020
private readonly DrivesViewModel drivesViewModel;
21+
private readonly NetworkDrivesViewModel networkDrivesViewModel;
2122
private IResourcesService resourcesService;
2223

2324
public IMultitaskingControl? MultitaskingControl { get; set; }
@@ -40,11 +41,13 @@ public MainPageViewModel(
4041
IUserSettingsService userSettings,
4142
IAppearanceSettingsService appearanceSettings,
4243
IResourcesService resources,
43-
DrivesViewModel drivesViewModel)
44+
DrivesViewModel drivesViewModel,
45+
NetworkDrivesViewModel networkDrivesViewModel)
4446
{
4547
userSettingsService = userSettings;
4648
appearanceSettingsService = appearanceSettings;
4749
this.drivesViewModel = drivesViewModel;
50+
this.networkDrivesViewModel = networkDrivesViewModel;
4851
resourcesService = resources;
4952
// Create commands
5053
NavigateToNumberedTabKeyboardAcceleratorCommand = new RelayCommand<KeyboardAcceleratorInvokedEventArgs>(NavigateToNumberedTabKeyboardAccelerator);
@@ -231,7 +234,7 @@ public async Task UpdateTabInfo(TabItem tabItem, object navigationArg)
231234
}
232235
else if (PathNormalization.NormalizePath(PathNormalization.GetPathRoot(currentPath)) == normalizedCurrentPath) // If path is a drive's root
233236
{
234-
var matchingDrive = App.NetworkDrivesManager.Drives.FirstOrDefault(netDrive => normalizedCurrentPath.Contains(PathNormalization.NormalizePath(netDrive.Path), StringComparison.OrdinalIgnoreCase));
237+
var matchingDrive = networkDrivesViewModel.Drives.Cast<DriveItem>().FirstOrDefault(netDrive => normalizedCurrentPath.Contains(PathNormalization.NormalizePath(netDrive.Path), StringComparison.OrdinalIgnoreCase));
235238
matchingDrive ??= drivesViewModel.Drives.Cast<DriveItem>().FirstOrDefault(drive => normalizedCurrentPath.Contains(PathNormalization.NormalizePath(drive.Path), StringComparison.OrdinalIgnoreCase));
236239
tabLocationHeader = matchingDrive is not null ? matchingDrive.Text : normalizedCurrentPath;
237240
}

0 commit comments

Comments
 (0)