Places Linux, refactor
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
namespace FileTime.GuiApp.IconProviders;
|
||||||
|
|
||||||
|
public enum SpecialPathType
|
||||||
|
{
|
||||||
|
Home,
|
||||||
|
Downloads,
|
||||||
|
Music,
|
||||||
|
Videos,
|
||||||
|
Desktop,
|
||||||
|
Documents,
|
||||||
|
Images,
|
||||||
|
Templates,
|
||||||
|
PublicShare
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using FileTime.App.Core.Services;
|
||||||
|
using FileTime.GuiApp.IconProviders;
|
||||||
|
|
||||||
|
namespace FileTime.GuiApp.Services;
|
||||||
|
|
||||||
|
public interface IPlacesService : IStartupHandler
|
||||||
|
{
|
||||||
|
Dictionary<string, SpecialPathType> GetSpecialPaths();
|
||||||
|
}
|
||||||
@@ -45,16 +45,20 @@ public static class Startup
|
|||||||
|
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
{
|
{
|
||||||
serviceCollection.AddSingleton<IContextMenuProvider, WindowsContextMenuProvider>();
|
serviceCollection
|
||||||
|
.AddSingleton<IContextMenuProvider, WindowsContextMenuProvider>()
|
||||||
|
.AddSingleton<IPlacesService, WindowsPlacesService>();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
serviceCollection.AddSingleton<IContextMenuProvider, LinuxContextMenuProvider>();
|
serviceCollection
|
||||||
|
.AddSingleton<IContextMenuProvider, LinuxContextMenuProvider>()
|
||||||
|
.AddSingleton<IPlacesService, LinuxPlacesService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
return serviceCollection
|
return serviceCollection
|
||||||
.AddSingleton<IStartupHandler, RootDriveInfoService>()
|
.AddSingleton<IStartupHandler, RootDriveInfoService>()
|
||||||
.AddSingleton<IStartupHandler, PlacesService>();
|
.AddSingleton<IStartupHandler>(sp => sp.GetRequiredService<IPlacesService>());
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static IServiceCollection RegisterLogging(this IServiceCollection serviceCollection)
|
internal static IServiceCollection RegisterLogging(this IServiceCollection serviceCollection)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using FileTime.Core.Models;
|
using FileTime.Core.Models;
|
||||||
using FileTime.GuiApp.Models;
|
using FileTime.GuiApp.Models;
|
||||||
|
using FileTime.GuiApp.Services;
|
||||||
using FileTime.Providers.Local;
|
using FileTime.Providers.Local;
|
||||||
using Syroot.Windows.IO;
|
|
||||||
|
|
||||||
namespace FileTime.GuiApp.IconProviders;
|
namespace FileTime.GuiApp.IconProviders;
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ public class MaterialIconProvider : IIconProvider
|
|||||||
private static readonly Dictionary<string, string> _iconsByExtension = new();
|
private static readonly Dictionary<string, string> _iconsByExtension = new();
|
||||||
private static readonly Dictionary<string, string> _iconsByFileName = new();
|
private static readonly Dictionary<string, string> _iconsByFileName = new();
|
||||||
|
|
||||||
private readonly List<SpecialPathWithIcon> _specialPaths = new();
|
private readonly Lazy<List<SpecialPathWithIcon>> _specialPaths;
|
||||||
public bool EnableAdvancedIcons { get; set; } = true;
|
public bool EnableAdvancedIcons { get; set; } = true;
|
||||||
|
|
||||||
static MaterialIconProvider()
|
static MaterialIconProvider()
|
||||||
@@ -19,17 +19,18 @@ public class MaterialIconProvider : IIconProvider
|
|||||||
InitMatches();
|
InitMatches();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MaterialIconProvider()
|
public MaterialIconProvider(IPlacesService placesService)
|
||||||
{
|
{
|
||||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return;
|
_specialPaths = new Lazy<List<SpecialPathWithIcon>>(() =>
|
||||||
|
{
|
||||||
|
var result = new List<SpecialPathWithIcon>();
|
||||||
|
foreach (var kvp in placesService.GetSpecialPaths())
|
||||||
|
{
|
||||||
|
result.Add(new SpecialPathWithIcon(kvp.Key, GetAssetPath(GetSpecialPathIcon(kvp.Value))));
|
||||||
|
}
|
||||||
|
|
||||||
_specialPaths.Add(new SpecialPathWithIcon(KnownFolders.Desktop.Path, GetAssetPath("desktop.svg")));
|
return result;
|
||||||
_specialPaths.Add(new SpecialPathWithIcon(KnownFolders.Documents.Path, GetAssetPath("folder-resource.svg")));
|
});
|
||||||
_specialPaths.Add(new SpecialPathWithIcon(KnownFolders.DownloadsLocalized.Path, GetAssetPath("folder-download.svg")));
|
|
||||||
_specialPaths.Add(new SpecialPathWithIcon(KnownFolders.MusicLocalized.Path, GetAssetPath("folder-music.svg")));
|
|
||||||
_specialPaths.Add(new SpecialPathWithIcon(KnownFolders.Pictures.Path, GetAssetPath("folder-images.svg")));
|
|
||||||
_specialPaths.Add(new SpecialPathWithIcon(KnownFolders.Profile.Path, GetAssetPath("folder-home.svg")));
|
|
||||||
_specialPaths.Add(new SpecialPathWithIcon(KnownFolders.Videos.Path, GetAssetPath("folder-video.svg")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImagePath GetImage(IItem item)
|
public ImagePath GetImage(IItem item)
|
||||||
@@ -40,13 +41,13 @@ public class MaterialIconProvider : IIconProvider
|
|||||||
|
|
||||||
if (!EnableAdvancedIcons) return GetAssetPath(icon);
|
if (!EnableAdvancedIcons) return GetAssetPath(icon);
|
||||||
|
|
||||||
if (localPath != null && _specialPaths.Find(p => p.Path == localPath) is SpecialPathWithIcon specialPath)
|
if (localPath != null && _specialPaths.Value.Find(p => p.Path == localPath) is SpecialPathWithIcon specialPath)
|
||||||
{
|
{
|
||||||
return specialPath.IconPath;
|
return specialPath.IconPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item is not IElement element) return GetAssetPath(icon);
|
if (item is not IElement element) return GetAssetPath(icon);
|
||||||
|
|
||||||
if (element.Provider is ILocalContentProvider && (localPath?.EndsWith(".svg") ?? false))
|
if (element.Provider is ILocalContentProvider && (localPath?.EndsWith(".svg") ?? false))
|
||||||
{
|
{
|
||||||
return new ImagePath(ImagePathType.Absolute, localPath);
|
return new ImagePath(ImagePathType.Absolute, localPath);
|
||||||
@@ -67,6 +68,21 @@ public class MaterialIconProvider : IIconProvider
|
|||||||
return GetAssetPath(icon);
|
return GetAssetPath(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetSpecialPathIcon(SpecialPathType pathType)
|
||||||
|
=> pathType switch
|
||||||
|
{
|
||||||
|
SpecialPathType.Desktop => "desktop.svg",
|
||||||
|
SpecialPathType.Documents => "folder-resource.svg",
|
||||||
|
SpecialPathType.Downloads => "folder-download.svg",
|
||||||
|
SpecialPathType.Music => "folder-music.svg",
|
||||||
|
SpecialPathType.Images => "folder-images.svg",
|
||||||
|
SpecialPathType.Home => "folder-home.svg",
|
||||||
|
SpecialPathType.Videos => "folder-video.svg",
|
||||||
|
SpecialPathType.Templates => "folder-resource.svg",
|
||||||
|
SpecialPathType.PublicShare => "folder-resource.svg",
|
||||||
|
_ => throw new NotImplementedException()
|
||||||
|
};
|
||||||
|
|
||||||
private static ImagePath GetAssetPath(string iconName)
|
private static ImagePath GetAssetPath(string iconName)
|
||||||
{
|
{
|
||||||
return new ImagePath(ImagePathType.Asset, "/Assets/material/" + iconName);
|
return new ImagePath(ImagePathType.Asset, "/Assets/material/" + iconName);
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using FileTime.Core.Models;
|
||||||
|
using FileTime.Core.Timeline;
|
||||||
|
using FileTime.GuiApp.IconProviders;
|
||||||
|
using FileTime.GuiApp.ViewModels;
|
||||||
|
using FileTime.Providers.Local;
|
||||||
|
|
||||||
|
namespace FileTime.GuiApp.Services;
|
||||||
|
|
||||||
|
public class LinuxPlacesService : IPlacesService
|
||||||
|
{
|
||||||
|
private readonly ILocalContentProvider _localContentProvider;
|
||||||
|
private readonly IGuiAppState _guiAppState;
|
||||||
|
private readonly Dictionary<string, SpecialPathType> _specialPath = new();
|
||||||
|
|
||||||
|
public LinuxPlacesService(
|
||||||
|
ILocalContentProvider localContentProvider,
|
||||||
|
IGuiAppState guiAppState)
|
||||||
|
{
|
||||||
|
_localContentProvider = localContentProvider;
|
||||||
|
_guiAppState = guiAppState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InitAsync()
|
||||||
|
{
|
||||||
|
var placeKeys = new Dictionary<string, SpecialPathType>
|
||||||
|
{
|
||||||
|
{"XDG_DESKTOP_DIR", SpecialPathType.Desktop},
|
||||||
|
{"XDG_DOWNLOAD_DIR", SpecialPathType.Downloads},
|
||||||
|
{"XDG_TEMPLATES_DIR", SpecialPathType.Templates},
|
||||||
|
{"XDG_PUBLICSHARE_DIR", SpecialPathType.PublicShare},
|
||||||
|
{"XDG_DOCUMENTS_DIR", SpecialPathType.Documents},
|
||||||
|
{"XDG_MUSIC_DIR", SpecialPathType.Music},
|
||||||
|
{"XDG_PICTURES_DIR", SpecialPathType.Images},
|
||||||
|
{"XDG_VIDEOS_DIR", SpecialPathType.Videos},
|
||||||
|
};
|
||||||
|
|
||||||
|
var homeFolder = Environment.GetEnvironmentVariable("HOME");
|
||||||
|
if (homeFolder is null) return;
|
||||||
|
|
||||||
|
var userDirsLines = await File.ReadAllLinesAsync(Path.Combine(homeFolder, ".config", "user-dirs.dirs"));
|
||||||
|
|
||||||
|
var placesStrings = placeKeys
|
||||||
|
.Select(p => (SpecialPath: p.Value, Line: userDirsLines.FirstOrDefault(l => l.StartsWith(p.Key))))
|
||||||
|
.Where(l => l.Line is not null)
|
||||||
|
.Select(l => (l.SpecialPath, Path: l.Line![(l.Line.IndexOf('=') + 1)..].Trim('\"')))
|
||||||
|
.Select(l => (l.SpecialPath, Path: ReplaceEnvVars(l.Path)))
|
||||||
|
.Where(l => Directory.Exists(l.Path))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var places = new List<PlaceInfo>();
|
||||||
|
foreach (var place in placesStrings)
|
||||||
|
{
|
||||||
|
var resolvedPlace = await _localContentProvider.GetItemByNativePathAsync(new NativePath(place.Path), PointInTime.Present);
|
||||||
|
|
||||||
|
if (resolvedPlace is not IContainer resolvedContainer) continue;
|
||||||
|
places.Add(new PlaceInfo(resolvedContainer, resolvedContainer.DisplayName));
|
||||||
|
_specialPath.Add(place.Path, place.SpecialPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
var resolvedHomeItem = await _localContentProvider.GetItemByNativePathAsync(new NativePath(homeFolder), PointInTime.Present);
|
||||||
|
|
||||||
|
|
||||||
|
IEnumerable<PlaceInfo> finalPlaces = places.OrderBy(p => p.DisplayName);
|
||||||
|
|
||||||
|
if (resolvedHomeItem is IContainer resolvedHomeFolder)
|
||||||
|
{
|
||||||
|
finalPlaces = finalPlaces.Prepend(new PlaceInfo(resolvedHomeFolder, resolvedHomeFolder.DisplayName));
|
||||||
|
_specialPath.Add(homeFolder, SpecialPathType.Home);
|
||||||
|
}
|
||||||
|
|
||||||
|
_guiAppState.Places = finalPlaces.ToList().AsReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ReplaceEnvVars(string s)
|
||||||
|
{
|
||||||
|
return Environment
|
||||||
|
.GetEnvironmentVariables()
|
||||||
|
.Cast<DictionaryEntry>()
|
||||||
|
.Select(d => new KeyValuePair<string, string>(d.Key.ToString()!, d.Value!.ToString()!))
|
||||||
|
.Aggregate(s, (c, kvp) => c.Replace("$" + kvp.Key, kvp.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, SpecialPathType> GetSpecialPaths() => _specialPath;
|
||||||
|
}
|
||||||
@@ -2,18 +2,19 @@ using System.Runtime.InteropServices;
|
|||||||
using FileTime.App.Core.Services;
|
using FileTime.App.Core.Services;
|
||||||
using FileTime.Core.Models;
|
using FileTime.Core.Models;
|
||||||
using FileTime.Core.Timeline;
|
using FileTime.Core.Timeline;
|
||||||
|
using FileTime.GuiApp.IconProviders;
|
||||||
using FileTime.GuiApp.ViewModels;
|
using FileTime.GuiApp.ViewModels;
|
||||||
using FileTime.Providers.Local;
|
using FileTime.Providers.Local;
|
||||||
using Syroot.Windows.IO;
|
using Syroot.Windows.IO;
|
||||||
|
|
||||||
namespace FileTime.GuiApp.Services;
|
namespace FileTime.GuiApp.Services;
|
||||||
|
|
||||||
public class PlacesService : IStartupHandler
|
public class WindowsPlacesService : IPlacesService
|
||||||
{
|
{
|
||||||
private readonly ILocalContentProvider _localContentProvider;
|
private readonly ILocalContentProvider _localContentProvider;
|
||||||
private readonly IGuiAppState _guiAppState;
|
private readonly IGuiAppState _guiAppState;
|
||||||
|
|
||||||
public PlacesService(
|
public WindowsPlacesService(
|
||||||
ILocalContentProvider localContentProvider,
|
ILocalContentProvider localContentProvider,
|
||||||
IGuiAppState guiAppState)
|
IGuiAppState guiAppState)
|
||||||
{
|
{
|
||||||
@@ -49,4 +50,16 @@ public class PlacesService : IStartupHandler
|
|||||||
|
|
||||||
_guiAppState.Places = places.AsReadOnly();
|
_guiAppState.Places = places.AsReadOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, SpecialPathType> GetSpecialPaths()
|
||||||
|
=> new Dictionary<string, SpecialPathType>
|
||||||
|
{
|
||||||
|
{KnownFolders.Desktop.Path, SpecialPathType.Desktop},
|
||||||
|
{KnownFolders.Documents.Path, SpecialPathType.Documents},
|
||||||
|
{KnownFolders.DownloadsLocalized.Path, SpecialPathType.Downloads},
|
||||||
|
{KnownFolders.MusicLocalized.Path, SpecialPathType.Music},
|
||||||
|
{KnownFolders.Pictures.Path, SpecialPathType.Images},
|
||||||
|
{KnownFolders.Profile.Path, SpecialPathType.Home},
|
||||||
|
{KnownFolders.Videos.Path, SpecialPathType.Videos},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user