diff --git a/.vscode/tasks.json b/.vscode/tasks.json index ed42e5b..72d76c5 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -72,7 +72,7 @@ "problemMatcher": "$msCompile" }, { - "label": "publish windows gui", + "label": "publish gui", "command": "dotnet", "type": "process", "args": [ @@ -80,8 +80,6 @@ "${workspaceFolder}/src/GuiApp/FileTime.Avalonia/FileTime.Avalonia.csproj", "-c", "Release", - "-r", - "win-x64" ], "problemMatcher": "$msCompile" }, diff --git a/src/GuiApp/FileTime.Avalonia/App.axaml b/src/GuiApp/FileTime.Avalonia/App.axaml index ff4532d..732cee5 100644 --- a/src/GuiApp/FileTime.Avalonia/App.axaml +++ b/src/GuiApp/FileTime.Avalonia/App.axaml @@ -129,7 +129,9 @@ - + + + diff --git a/src/GuiApp/FileTime.Avalonia/Converters/DateTimeConverter.cs b/src/GuiApp/FileTime.Avalonia/Converters/DateTimeConverter.cs new file mode 100644 index 0000000..ec49b92 --- /dev/null +++ b/src/GuiApp/FileTime.Avalonia/Converters/DateTimeConverter.cs @@ -0,0 +1,19 @@ +using System; +using System.Globalization; +using Avalonia.Data.Converters; + +namespace FileTime.Avalonia.Converters +{ + public class DateTimeConverter : IValueConverter + { + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) => + value is DateTime dateTime && parameter is string parameterS + ? dateTime.ToString(parameterS) + : value; + + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/src/GuiApp/FileTime.Avalonia/Converters/IsElementConverter.cs b/src/GuiApp/FileTime.Avalonia/Converters/IsTypeConverter.cs similarity index 69% rename from src/GuiApp/FileTime.Avalonia/Converters/IsElementConverter.cs rename to src/GuiApp/FileTime.Avalonia/Converters/IsTypeConverter.cs index faa2d69..58bdd4c 100644 --- a/src/GuiApp/FileTime.Avalonia/Converters/IsElementConverter.cs +++ b/src/GuiApp/FileTime.Avalonia/Converters/IsTypeConverter.cs @@ -1,13 +1,13 @@ using System; using System.Globalization; using Avalonia.Data.Converters; -using FileTime.Core.Models; namespace FileTime.Avalonia.Converters { - public class IsElementConverter : IValueConverter + public class IsTypeConverter : IValueConverter { - public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) => value is IElement; + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) => + parameter is Type type && type.IsInstanceOfType(value); public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { diff --git a/src/GuiApp/FileTime.Avalonia/Converters/ItemViewModelToAttibuteTypeConverter.cs b/src/GuiApp/FileTime.Avalonia/Converters/ItemViewModelToAttibuteTypeConverter.cs new file mode 100644 index 0000000..890aa18 --- /dev/null +++ b/src/GuiApp/FileTime.Avalonia/Converters/ItemViewModelToAttibuteTypeConverter.cs @@ -0,0 +1,40 @@ +using System; +using System.Globalization; +using Avalonia.Data.Converters; +using FileTime.Avalonia.Models; +using FileTime.Avalonia.ViewModels; +using FileTime.Providers.Local; + +namespace FileTime.Avalonia.Converters +{ + public class ItemViewModelIsAttibuteTypeConverter : IValueConverter + { + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + return parameter is AttibuteType targetAttribute && GetAttibuteType(value) == targetAttribute; + } + + private static AttibuteType? GetAttibuteType(object? value) + { + if (value is ElementViewModel elementVM) + { + if (elementVM.Element is LocalFile) + { + return AttibuteType.LocalFile; + } + return AttibuteType.Element; + } + else if (value is ContainerViewModel) + { + return AttibuteType.Container; + } + + return null; + } + + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/src/GuiApp/FileTime.Avalonia/FileTime.Avalonia.csproj b/src/GuiApp/FileTime.Avalonia/FileTime.Avalonia.csproj index 3554aea..951a285 100644 --- a/src/GuiApp/FileTime.Avalonia/FileTime.Avalonia.csproj +++ b/src/GuiApp/FileTime.Avalonia/FileTime.Avalonia.csproj @@ -5,6 +5,17 @@ enable Assets\filetime.ico + + true + full + DEBUG;TRACE + Development + + + pdbonly + true + Production + @@ -46,9 +57,7 @@ MainWindow.axaml - - - PreserveNewest - + + diff --git a/src/GuiApp/FileTime.Avalonia/Models/AttibuteType.cs b/src/GuiApp/FileTime.Avalonia/Models/AttibuteType.cs new file mode 100644 index 0000000..feb9b9e --- /dev/null +++ b/src/GuiApp/FileTime.Avalonia/Models/AttibuteType.cs @@ -0,0 +1,9 @@ +namespace FileTime.Avalonia.Models +{ + public enum AttibuteType + { + LocalFile, + Element, + Container + } +} \ No newline at end of file diff --git a/src/GuiApp/FileTime.Avalonia/ViewModels/ContainerViewModel.cs b/src/GuiApp/FileTime.Avalonia/ViewModels/ContainerViewModel.cs index 8cf97c3..557ba5b 100644 --- a/src/GuiApp/FileTime.Avalonia/ViewModels/ContainerViewModel.cs +++ b/src/GuiApp/FileTime.Avalonia/ViewModels/ContainerViewModel.cs @@ -158,8 +158,31 @@ namespace FileTime.Avalonia.ViewModels { _isRefreshing = true; - var containers = (await _container.GetContainers())!.Select(c => AdoptOrReuseOrCreateItem(c, alloweReuse , (c2) => new ContainerViewModel(_newItemProcessor, this, c2, ItemNameConverterService))).ToList(); - var elements = (await _container.GetElements())!.Select(e => AdoptOrReuseOrCreateItem(e, alloweReuse , (e2) => new ElementViewModel(e2, this, ItemNameConverterService))).ToList(); + List newContainers = new List(); + List newElements = new List(); + + if (await _container.GetContainers() is IReadOnlyList containers) + { + foreach (var container in containers) + { + newContainers.Add(await AdoptOrReuseOrCreateItem(container, alloweReuse, (c2) => new ContainerViewModel(_newItemProcessor, this, c2, ItemNameConverterService))); + } + } + + if(await _container.GetElements() is IReadOnlyList elements) + { + foreach(var element in elements) + { + var generator = async (IElement e) => + { + var element = new ElementViewModel(e, this, ItemNameConverterService); + await element.Init(); + return element; + }; + + newElements.Add(await AdoptOrReuseOrCreateItem(element, alloweReuse, generator)); + } + } if (token.IsCancellationRequested) return; @@ -167,55 +190,22 @@ namespace FileTime.Avalonia.ViewModels if (initializeChildren) { - foreach (var container in containers) + foreach (var container in newContainers) { if (token.IsCancellationRequested) return; await container.Init(false, token); } } - /*var containersToAdd = containers.Except(_containers).ToList(); - var containersToRemove = _containers.Except(containers).ToList(); - - var elementsToAdd = elements.Except(_elements).ToList(); - var elementsToRemove = _elements.Except(elements).ToList(); - - foreach (var containerToRemove in containersToRemove) - { - Containers.Remove(containerToRemove); - Items.Remove(containerToRemove); - containerToRemove?.Dispose(); - } - - foreach (var elementToRemove in elementsToRemove) - { - Elements.Remove(elementToRemove); - Items.Remove(elementToRemove); - } - - foreach (var containerToAdd in containersToAdd) - { - Containers.Insert(GetNewItemPosition(containerToAdd, Containers), containerToAdd); - Items.Insert(GetNewItemPosition(containerToAdd, Items), containerToAdd); - } - - foreach (var elementToAdd in elementsToAdd) - { - Elements.Insert(GetNewItemPosition(elementToAdd, Elements), elementToAdd); - Items.Insert(GetNewItemPosition(elementToAdd, Items), elementToAdd); - }*/ - - - - var containersToRemove = _containers.Except(containers).ToList(); + var containersToRemove = _containers.Except(newContainers).ToList(); foreach (var containerToRemove in containersToRemove) { containerToRemove?.Dispose(); } - Containers = new ObservableCollection(containers); - Elements = new ObservableCollection(elements); - Items = new ObservableCollection(containers.Cast().Concat(elements)); + Containers = new ObservableCollection(newContainers); + Elements = new ObservableCollection(newElements); + Items = new ObservableCollection(newContainers.Cast().Concat(newElements)); for (var i = 0; i < Items.Count; i++) { @@ -247,18 +237,27 @@ namespace FileTime.Avalonia.ViewModels return i; } - private TResult AdoptOrReuseOrCreateItem(T item, bool allowResuse, Func generator) where T : class, IItem + private async Task AdoptOrReuseOrCreateItem(T item, bool allowResuse, Func generator) where T : class, IItem + { + return await AdoptOrReuseOrCreateItem(item, allowResuse, Helper); + + Task Helper(T item) + { + return Task.FromResult(generator(item)); + } + } + private async Task AdoptOrReuseOrCreateItem(T item, bool allowResuse, Func> generator) where T : class, IItem { var itemToAdopt = ChildrenToAdopt.Find(i => i.Item == item); if (itemToAdopt is TResult itemViewModel) return itemViewModel; if (allowResuse) { - var existingViewModel = _items?.FirstOrDefault(i => i.Item == item); - if (existingViewModel is TResult itemViewModelToReuse) return itemViewModelToReuse; + var existingViewModel = _items?.FirstOrDefault(i => i.Item == item); + if (existingViewModel is TResult itemViewModelToReuse) return itemViewModelToReuse; } - return generator(item); + return await generator(item); } public void Unload(bool recursive = true) diff --git a/src/GuiApp/FileTime.Avalonia/ViewModels/ElementViewModel.cs b/src/GuiApp/FileTime.Avalonia/ViewModels/ElementViewModel.cs index cb2723e..d436f72 100644 --- a/src/GuiApp/FileTime.Avalonia/ViewModels/ElementViewModel.cs +++ b/src/GuiApp/FileTime.Avalonia/ViewModels/ElementViewModel.cs @@ -3,6 +3,7 @@ using FileTime.Avalonia.Models; using FileTime.Avalonia.Services; using MvvmGen; using System.Collections.Generic; +using System.Threading.Tasks; namespace FileTime.Avalonia.ViewModels { @@ -27,6 +28,9 @@ namespace FileTime.Avalonia.ViewModels [Property] private ContainerViewModel? _parent; + [Property] + private long _size; + [PropertyInvalidate(nameof(IsSelected))] [PropertyInvalidate(nameof(IsAlternative))] [PropertyInvalidate(nameof(IsMarked))] @@ -50,5 +54,10 @@ namespace FileTime.Avalonia.ViewModels } public void InvalidateDisplayName() => OnPropertyChanged(nameof(DisplayName)); + + public async Task Init() + { + Size = await _element.GetElementSize(); + } } } diff --git a/src/GuiApp/FileTime.Avalonia/Views/ItemView.axaml b/src/GuiApp/FileTime.Avalonia/Views/ItemView.axaml index ac02581..c48c4e9 100644 --- a/src/GuiApp/FileTime.Avalonia/Views/ItemView.axaml +++ b/src/GuiApp/FileTime.Avalonia/Views/ItemView.axaml @@ -4,6 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="FileTime.Avalonia.Views.ItemView" + xmlns:models="using:FileTime.Avalonia.Models" x:Name="ItemRoot" Background="{Binding ViewMode,Converter={StaticResource ItemViewModeToBackgroundConverter}}"> @@ -40,9 +41,27 @@ - - - + + + + + + + + + + + + + + + + + +