Skip to content

Commit

Permalink
Fix file access problems
Browse files Browse the repository at this point in the history
  • Loading branch information
SuperJMN committed Oct 18, 2023
1 parent 397d96b commit bfcd38f
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 89 deletions.
8 changes: 4 additions & 4 deletions AvaloniaSyncer.Tests/AvaloniaSyncer.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Zafiro.FileSystem" Version="4.0.27" />
<PackageReference Include="Zafiro.FileSystem.Local" Version="4.0.27" />
<PackageReference Include="Zafiro.FileSystem.SeaweedFS" Version="4.0.27" />
<PackageReference Include="Zafiro.FileSystem.Sftp" Version="4.0.27" />
<PackageReference Include="Zafiro.FileSystem" Version="4.0.29" />
<PackageReference Include="Zafiro.FileSystem.Local" Version="4.0.29" />
<PackageReference Include="Zafiro.FileSystem.SeaweedFS" Version="4.0.29" />
<PackageReference Include="Zafiro.FileSystem.Sftp" Version="4.0.29" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\src\AvaloniaSyncer\AvaloniaSyncer.csproj" />
Expand Down
2 changes: 1 addition & 1 deletion src/AvaloniaSyncer/App.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public override void OnFrameworkInitializationCompleted()
{
var sections = new List<Section>
{
new("Explore", vm.GetExploreSection()),
new("Explore", await vm.GetExploreSection()),
new("Synchronize", await vm.GetSynchronizationSection()),
new("Settings", await vm.GetConnectionsViewModel())
};
Expand Down
6 changes: 3 additions & 3 deletions src/AvaloniaSyncer/AvaloniaSyncer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
<PackageReference Include="Zafiro.Avalonia" Version="3.0.42" />
<PackageReference Include="Zafiro.Avalonia.Dialogs" Version="3.0.42" />
<PackageReference Include="Zafiro.Avalonia.FileExplorer" Version="1.0.14" />
<PackageReference Include="Zafiro.FileSystem.Local" Version="4.0.27" />
<PackageReference Include="Zafiro.FileSystem.SeaweedFS" Version="4.0.27" />
<PackageReference Include="Zafiro.FileSystem.Sftp" Version="4.0.27" />
<PackageReference Include="Zafiro.FileSystem.Local" Version="4.0.29" />
<PackageReference Include="Zafiro.FileSystem.SeaweedFS" Version="4.0.29" />
<PackageReference Include="Zafiro.FileSystem.Sftp" Version="4.0.29" />
<PackageReference Include="Zafiro.UI" Version="4.0.11" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,11 @@ internal class ConnectionsRepository : IConnectionsRepository
private readonly SourceCache<IFileSystemConnection, string> connectionsSource = new(x => x.Name);
private readonly ConfigurationStore store;

private ConnectionsRepository(Maybe<ILogger> logger)

public ConnectionsRepository(IEnumerable<IFileSystemConnection> connections, Maybe<ILogger> logger, ConfigurationStore store)
{
this.store = store;
this.logger = logger;
store = new ConfigurationStore(() => File.OpenRead("Connections.json"), () => File.Open("Connections.json", FileMode.Create, FileAccess.Write));
}

public ConnectionsRepository(IEnumerable<IFileSystemConnection> connections, Maybe<ILogger> logger) : this(logger)
{
connectionsSource.AddOrUpdate(connections);
connectionsSource.Connect().Bind(out this.connections).Subscribe();
}
Expand Down
32 changes: 12 additions & 20 deletions src/AvaloniaSyncer/Sections/Explorer/ExplorerSectionView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,18 @@
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaSyncer.Sections.Explorer.ExplorerSectionView"
x:DataType="explorer:ExplorerSectionViewModel">
<DockPanel>
<Button IsVisible="False" Content="Load" Command="{Binding Load}" DockPanel.Dock="Top" />
<TabControl ItemsSource="{Binding Connections}">
<TabControl.ItemTemplate>
<DataTemplate DataType="explorer:FileSystemConnectionViewModel">
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate DataType="explorer:FileSystemConnectionViewModel">
<ContentControl Content="{Binding}" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</DockPanel>

<Interaction.Behaviors>
<RoutedEventTriggerBehavior RoutedEvent="{x:Static Control.LoadedEvent}">
<InvokeCommandAction Command="{Binding Load}" />
</RoutedEventTriggerBehavior>
</Interaction.Behaviors>
<TabControl ItemsSource="{Binding Connections}">
<TabControl.ItemTemplate>
<DataTemplate DataType="explorer:FileSystemConnectionViewModel">
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate DataType="explorer:FileSystemConnectionViewModel">
<ContentControl Content="{Binding}" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>

</UserControl>
48 changes: 12 additions & 36 deletions src/AvaloniaSyncer/Sections/Explorer/ExplorerSectionViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,53 +1,29 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;
using System.Threading.Tasks;
using AvaloniaSyncer.Sections.Explorer.FileSystemConnections;
using AvaloniaSyncer.Sections.Explorer.FileSystemConnections.Serialization;
using AvaloniaSyncer.Sections.Connections;
using CSharpFunctionalExtensions;
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
using Serilog;
using Zafiro.Avalonia.FileExplorer.Clipboard;
using Zafiro.Avalonia.FileExplorer.TransferManager;
using Zafiro.CSharpFunctionalExtensions;
using Zafiro.FileSystem;
using Zafiro.UI;

namespace AvaloniaSyncer.Sections.Explorer;

public class ExplorerSectionViewModel : ReactiveObject
{
private readonly Maybe<ILogger> logger;
private readonly ObservableAsPropertyHelper<IList<FileSystemConnectionViewModel>> connections;
private readonly ReadOnlyObservableCollection<FileSystemConnectionViewModel> connections;

public ExplorerSectionViewModel(INotificationService notificationService, IClipboard clipboard, ITransferManager transferManager, Maybe<ILogger> logger)
public ExplorerSectionViewModel(IConnectionsRepository repository, INotificationService notificationService, IClipboard clipboard, ITransferManager transferManager, Maybe<ILogger> logger)
{
this.logger = logger;
Load = ReactiveCommand.CreateFromObservable(() => Observable.FromAsync(() => GetConnections())
.Successes()
.SelectMany(x => x)
.Select(connection => new FileSystemConnectionViewModel(connection, notificationService, clipboard, transferManager)).ToList());
Load.Subscribe(model => { });

connections = Load.ToProperty(this, x => x.Connections);
}

public ReactiveCommand<Unit, IList<FileSystemConnectionViewModel>> Load { get; }

public IList<FileSystemConnectionViewModel> Connections => connections.Value;

private async Task<Result<ReadOnlyObservableCollection<IFileSystemConnection>>> GetConnections()
{
var store = new ConfigurationStore(() => File.OpenRead("Connections.json"), () => File.OpenWrite("Connections.json"));
var configs = await Async.Await(() => store.Load())
.Map(enumerable => enumerable.Select(connection => Mapper.ToSystem(connection, logger)))
.Map(enumerable => new FileSystemConnectionRepository(enumerable))
.Map(r => r.Connections);

return configs;
repository.Connections
.ToObservableChangeSet(x => x.Name)
.Transform(connection => new FileSystemConnectionViewModel(connection, notificationService, clipboard, transferManager))
.Bind(out connections)
.Subscribe();
}

public ReadOnlyObservableCollection<FileSystemConnectionViewModel> Connections => connections;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,27 @@ namespace AvaloniaSyncer.Sections.Explorer.FileSystemConnections.Serialization;

public class ConfigurationStore
{
private readonly Func<Stream> read;
private readonly Func<Stream> write;
private readonly Func<Result<Stream>> read;
private readonly Func<Result<Stream>> write;

public ConfigurationStore(Func<Stream> read, Func<Stream> write)
public ConfigurationStore(Func<Result<Stream>> read, Func<Result<Stream>> write)
{
this.read = read;
this.write = write;
}

public Task<Result<IEnumerable<Connection>>> Load()
{
return Result
.Try(async () =>
return read()
.Bind(stream =>
{
using (var utf8Json = read())
return Result.Try(async () =>
{
return await JsonSerializer.DeserializeAsync<IEnumerable<Connection>>(utf8Json);
}
using (stream)
{
return await JsonSerializer.DeserializeAsync<IEnumerable<Connection>>(stream);
}
});
})
.OnFailureCompensate(() => Task.FromResult(Result.Success(Enumerable.Empty<Connection>())))
.Bind(list =>
Expand All @@ -44,12 +47,16 @@ public Task<Result<IEnumerable<Connection>>> Load()

public Task<Result> Save(IEnumerable<Connection> connections)
{
return Result.Try(async () =>
{
await using (var utf8Json = write())
return write()
.Bind(stream =>
{
await JsonSerializer.SerializeAsync(utf8Json, connections);
}
});
return Result.Try(async () =>
{
using (stream)
{
await JsonSerializer.SerializeAsync(stream, connections);
}
});
});
}
}
12 changes: 7 additions & 5 deletions src/AvaloniaSyncer/ViewModelFactory.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Reactive.Linq;
using System.Threading.Tasks;
Expand All @@ -17,6 +18,7 @@
using Zafiro.Avalonia.FileExplorer.Clipboard;
using Zafiro.Avalonia.FileExplorer.TransferManager;
using Zafiro.Avalonia.Notifications;
using Zafiro.FileSystem;

namespace AvaloniaSyncer;

Expand Down Expand Up @@ -54,9 +56,9 @@ public async Task<SyncronizationSectionViewModel> GetSynchronizationSection()
TransferManager, Logger);
}

public ExplorerSectionViewModel GetExploreSection()
public async Task<ExplorerSectionViewModel> GetExploreSection()
{
return new ExplorerSectionViewModel(NotificationService, Clipboard, TransferManager, Logger);
return new ExplorerSectionViewModel(await ConnectionsRepository, NotificationService, Clipboard, TransferManager, Logger);
}

public async Task<ConnectionsSectionViewModel> GetConnectionsViewModel()
Expand All @@ -83,10 +85,10 @@ private IObservable<IConnectionsRepository> GetConnectionsRepository(Maybe<ILogg
{
return Observable.FromAsync(async () =>
{
var store = new ConfigurationStore(() => File.OpenRead("Connections.json"), () => File.OpenWrite("Connections.json"));
var store = new ConfigurationStore(() => ApplicationStorage.OpenRead("Connections"), () => ApplicationStorage.OpenWrite("Connections"));
var loadResult = await store.Load();
var result = loadResult.Map(enumerable => new ConnectionsRepository(enumerable.Select(x => Mapper.ToSystem(x, logger)), logger));
var repo = result.GetValueOrDefault(() => new ConnectionsRepository(Enumerable.Empty<IFileSystemConnection>(), logger));
var result = loadResult.Map(enumerable => new ConnectionsRepository(enumerable.Select(x => Mapper.ToSystem(x, logger)), logger, store));
var repo = result.GetValueOrDefault(() => new ConnectionsRepository(Enumerable.Empty<IFileSystemConnection>(), logger, store));
return repo;
}).Replay()
.RefCount();
Expand Down

0 comments on commit bfcd38f

Please sign in to comment.