* Update ReactiveUI
* Autorefresh feature
* Borders, structural equality
* Update gui on uwp
* Update Avalonia pic
* Disable buttons while refreshing
* Mention ReactiveUI
* Fix spacing issues on uwp
* Fix IsCurrentPathEmpty skipping signals
This commit is contained in:
Artyom 2019-01-29 22:27:27 +03:00 коммит произвёл GitHub
Родитель 9a28d291c5
Коммит e04bdf6b2a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
16 изменённых файлов: 257 добавлений и 143 удалений

3
.gitignore поставляемый
Просмотреть файл

@ -328,3 +328,6 @@ ASALocalRun/
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Fody files
*.xsd

Просмотреть файл

@ -9,6 +9,7 @@
<PackageReference Include="Avalonia" Version="0.7.0" />
<PackageReference Include="Avalonia.Desktop" Version="0.7.0" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.7.0" />
<PackageReference Include="Splat.NLog" Version="1.0.5.0" />
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -4,9 +4,9 @@ using Camelotia.Presentation.Avalonia.Services;
using Camelotia.Presentation.Interfaces;
using Camelotia.Presentation.ViewModels;
using Camelotia.Services.Providers;
using Camelotia.Services.Storages;
using ReactiveUI;
using Avalonia;
using Camelotia.Services.Storages;
namespace Camelotia.Presentation.Avalonia
{

Просмотреть файл

@ -5,23 +5,24 @@
xmlns:models="clr-namespace:Camelotia.Services.Models;assembly=Camelotia.Services"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:Camelotia.Presentation.Avalonia.Views"
mc:Ignorable="d" Background="#ffffff">
mc:Ignorable="d" Background="#f7f7f7">
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="42" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="4*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0"
Command="{Binding Back}"
HorizontalAlignment="Stretch"
Classes="Rounded"
Content="Back" />
<TextBlock Grid.Column="1"
@ -31,108 +32,134 @@
Margin="15 0" />
<Button Grid.Column="2"
Command="{Binding Open}"
HorizontalAlignment="Stretch"
Classes="Rounded"
Content="Open" />
<Button Grid.Column="3"
Command="{Binding Refresh}"
Classes="Rounded"
Content="Refresh" />
</Grid>
<Grid Grid.Row="1">
<ListBox Padding="0"
Foreground="#000000"
SelectionMode="Toggle"
Items="{Binding Files}"
BorderBrush="Transparent"
IsVisible="{Binding IsReady}"
SelectedItem="{Binding SelectedFile, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate DataType="models:FileModel">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<StackPanel Margin="8" Grid.Column="0">
<TextBlock Text="{Binding Name}"
TextWrapping="Wrap"
FontSize="14" />
<TextBlock Text="Directory"
IsVisible="{Binding IsFolder}"
Foreground="#777777"
FontSize="12" />
</StackPanel>
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
Foreground="#999999"
Text="{Binding Size}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Grid IsVisible="{Binding HasErrors}" Background="#ffffff">
<StackPanel VerticalAlignment="Center">
<Ellipse Width="10" Height="10"
HorizontalAlignment="Center"
Fill="#ff0000"
Margin="10" />
<TextBlock HorizontalAlignment="Center"
Text="Can't perform the operation, an error has occured."
Foreground="#000000" />
</StackPanel>
<Border Grid.Row="1" BorderBrush="#f2f2f2" BorderThickness="0 2 0 2">
<Grid>
<ListBox Padding="0"
BorderThickness="0"
Background="Transparent"
SelectionMode="Toggle"
Items="{Binding Files}"
IsVisible="{Binding IsReady}"
SelectedItem="{Binding SelectedFile, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate DataType="models:FileModel">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<StackPanel Margin="8" Grid.Column="0">
<TextBlock Text="{Binding Name}"
TextWrapping="Wrap"
FontSize="14" />
<TextBlock Text="Directory"
IsVisible="{Binding IsFolder}"
Foreground="#777777"
FontSize="12" />
</StackPanel>
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
Foreground="#999999"
Text="{Binding Size}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Grid IsVisible="{Binding HasErrors}" Background="#f7f7f7">
<StackPanel VerticalAlignment="Center">
<Ellipse Width="10" Height="10"
HorizontalAlignment="Center"
Fill="#ff0000"
Margin="10" />
<TextBlock HorizontalAlignment="Center"
Text="Can't perform the operation, an error has occured."
Foreground="#000000" />
</StackPanel>
</Grid>
<Grid IsVisible="{Binding IsCurrentPathEmpty}" Background="#f7f7f7">
<StackPanel VerticalAlignment="Center">
<Ellipse Width="10" Height="10"
HorizontalAlignment="Center"
Fill="#ff0000"
Margin="10" />
<TextBlock HorizontalAlignment="Center"
Text="Whoops, no files here!"
Foreground="#000000" />
</StackPanel>
</Grid>
<Grid IsVisible="{Binding IsLoading}" Background="#f7f7f7">
<StackPanel VerticalAlignment="Center">
<ProgressBar HorizontalAlignment="Stretch"
IsIndeterminate="{Binding IsLoading}" />
<TextBlock HorizontalAlignment="Center"
Text="Please, wait..."
Foreground="#000000" />
</StackPanel>
</Grid>
</Grid>
<Grid IsVisible="{Binding IsCurrentPathEmpty}" Background="#ffffff">
<StackPanel VerticalAlignment="Center">
<Ellipse Width="10" Height="10"
HorizontalAlignment="Center"
Fill="#ff0000"
Margin="10" />
<TextBlock HorizontalAlignment="Center"
Text="Whoops, no files here!"
Foreground="#000000" />
</StackPanel>
</Grid>
<Grid IsVisible="{Binding IsLoading}" Background="#ffffff">
<StackPanel VerticalAlignment="Center">
<ProgressBar HorizontalAlignment="Stretch"
IsIndeterminate="{Binding IsLoading}" />
<TextBlock HorizontalAlignment="Center"
Text="Please, wait..."
Foreground="#000000" />
</StackPanel>
</Grid>
</Grid>
</Border>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0"
Content="Logout"
Classes="Rounded"
IsVisible="{Binding CanLogout}"
Command="{Binding Logout}" />
<Button Grid.Column="1"
Content="Delete"
Classes="Rounded"
HorizontalAlignment="Stretch"
Command="{Binding DeleteSelectedFile}" />
<StackPanel Grid.Column="2" Orientation="Horizontal" Margin="10">
<StackPanel Grid.Column="1" Orientation="Horizontal"
Margin="5" VerticalAlignment="Center">
<TextBlock Text="You selected: " Foreground="#aaaaaa" />
<TextBlock Text="{Binding SelectedFile.Name}"
Foreground="#888888" />
</StackPanel>
<Button Grid.Column="3"
<Button Grid.Column="2"
Content="Upload"
Classes="Rounded"
HorizontalAlignment="Stretch"
Command="{Binding UploadToCurrentPath}" />
<Button Grid.Column="4"
<Button Grid.Column="3"
Content="Download"
Classes="Rounded"
HorizontalAlignment="Stretch"
Command="{Binding DownloadSelectedFile}" />
</Grid>
<Grid Grid.Row="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0"
Content="Logout"
Classes="Rounded"
HorizontalAlignment="Stretch"
Command="{Binding Logout}" />
<Button Grid.Column="1"
Content="Unselect"
Classes="Rounded"
HorizontalAlignment="Stretch"
Command="{Binding UnselectFile}" />
<StackPanel Grid.Column="2" Orientation="Horizontal"
Margin="5" VerticalAlignment="Center">
<TextBlock Text="Refreshing in: " Foreground="#aaaaaa" />
<TextBlock Text="{Binding RefreshingIn}"
Foreground="#888888" />
</StackPanel>
<Button Grid.Column="3"
Content="Refresh"
Classes="Rounded"
HorizontalAlignment="Stretch"
Command="{Binding Refresh}" />
</Grid>
</Grid>
<Grid IsVisible="{Binding Auth.IsAnonymous}">
<views:AuthView DataContext="{Binding Auth}" />

Просмотреть файл

@ -11,7 +11,7 @@
</PackageReference>
<PackageReference Include="FluentAssertions" Version="5.5.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="ReactiveUI.Testing" Version="9.5.1" />
<PackageReference Include="ReactiveUI.Testing" Version="9.8.23" />
<PackageReference Include="NSubstitute" Version="3.1.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">

Просмотреть файл

@ -15,13 +15,13 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Margin="6"
Style="{StaticResource ButtonRevealStyle}"
@ -33,16 +33,11 @@
VerticalAlignment="Center"
FontSize="14"
Margin="15 0" />
<Button Grid.Column="2" Margin="6 6 0 6"
<Button Grid.Column="2" Margin="6"
Style="{StaticResource AccentButtonStyle}"
HorizontalAlignment="Stretch"
Command="{x:Bind ViewModel.Open, Mode=OneWay}"
Content="Open" />
<Button Grid.Column="3" Margin="6"
Style="{StaticResource ButtonRevealStyle}"
HorizontalAlignment="Stretch"
Command="{x:Bind ViewModel.Refresh, Mode=OneWay}"
Content="Refresh" />
</Grid>
<Grid Grid.Row="1">
<ListBox BorderBrush="Transparent"
@ -60,20 +55,33 @@
<DataTemplate x:DataType="models:FileModel">
<Grid Margin="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="&#x1F4C1;"
FontFamily="Segoe UI Symbol"
Foreground="{ThemeResource ApplicationSecondaryForegroundThemeBrush}"
Visibility="{x:Bind IsFolder}"
FontSize="14" />
<TextBlock Grid.Column="0"
Text="&#xE729;"
FontFamily="Segoe MDL2 Assets"
Foreground="{ThemeResource AppBarSeparatorForegroundThemeBrush}"
Visibility="{x:Bind IsFile}"
FontSize="14" />
<TextBlock Grid.Column="1"
Text="{x:Bind Name, Mode=OneTime}"
TextWrapping="Wrap"
FontSize="14" />
<TextBlock Grid.Column="1"
<TextBlock Grid.Column="2"
Text="Directory"
Visibility="{x:Bind IsFolder, Mode=OneTime}"
Foreground="{ThemeResource ApplicationSecondaryForegroundThemeBrush}"
FontSize="12" />
<TextBlock Grid.Column="2"
<TextBlock Grid.Column="3"
VerticalAlignment="Center"
Foreground="{ThemeResource ApplicationSecondaryForegroundThemeBrush}"
Text="{x:Bind Size, Mode=OneTime}" />
@ -115,37 +123,64 @@
</Grid>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0"
Content="Logout" Margin="6 6 0 6"
Style="{StaticResource ButtonRevealStyle}"
Visibility="{x:Bind ViewModel.CanLogout, Mode=OneWay}"
Command="{x:Bind ViewModel.Logout, Mode=OneWay}" />
<Button Grid.Column="1"
Content="Delete" Margin="6 6 3 6"
HorizontalAlignment="Stretch"
Content="Delete" Margin="6 6 0 3"
Style="{StaticResource ButtonRevealStyle}"
Command="{x:Bind ViewModel.DeleteSelectedFile, Mode=OneWay}" />
<StackPanel Grid.Column="2" Orientation="Horizontal" Margin="10">
<StackPanel Grid.Column="1" Orientation="Horizontal" Margin="10">
<TextBlock Text="You selected:"
Margin="0 0 3 0" TextTrimming="CharacterEllipsis"
Foreground="{ThemeResource ApplicationSecondaryForegroundThemeBrush}" />
<TextBlock Text="{x:Bind ViewModel.SelectedFile.Name, Mode=OneWay}"
Foreground="{ThemeResource AppBarSeparatorForegroundThemeBrush}" />
</StackPanel>
<Button Grid.Column="3"
Content="Upload" Margin="6 6 0 6"
<Button Grid.Column="2"
HorizontalAlignment="Stretch"
Content="Upload" Margin="6 6 0 3"
Style="{StaticResource ButtonRevealStyle}"
Command="{x:Bind ViewModel.UploadToCurrentPath, Mode=OneWay}" />
<Button Grid.Column="4"
Content="Download" Margin="6"
<Button Grid.Column="3"
HorizontalAlignment="Stretch"
Content="Download" Margin="6 6 6 3"
Style="{StaticResource ButtonRevealStyle}"
Command="{x:Bind ViewModel.DownloadSelectedFile, Mode=OneWay}" />
</Grid>
<Grid Grid.Row="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="5*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0"
HorizontalAlignment="Stretch"
Content="Logout" Margin="6 3 0 6"
Style="{StaticResource ButtonRevealStyle}"
Command="{x:Bind ViewModel.Logout, Mode=OneWay}" />
<Button Grid.Column="1"
HorizontalAlignment="Stretch"
Content="Unselect" Margin="6 3 0 6"
Style="{StaticResource ButtonRevealStyle}"
Command="{x:Bind ViewModel.UnselectFile, Mode=OneWay}" />
<StackPanel Grid.Column="2" Orientation="Horizontal" Margin="10">
<TextBlock Text="Refreshing in:"
Margin="0 0 3 0" TextTrimming="CharacterEllipsis"
Foreground="{ThemeResource ApplicationSecondaryForegroundThemeBrush}" />
<TextBlock Text="{x:Bind ViewModel.RefreshingIn, Mode=OneWay}"
Foreground="{ThemeResource AppBarSeparatorForegroundThemeBrush}" />
</StackPanel>
<Button Grid.Column="3" Margin="6 3 6 6"
Style="{StaticResource AccentButtonStyle}"
HorizontalAlignment="Stretch"
Command="{x:Bind ViewModel.Refresh, Mode=OneWay}"
Content="Refresh" />
</Grid>
</Grid>
<Grid Visibility="{x:Bind ViewModel.Auth.IsAnonymous, Mode=OneWay}"
Background="{ThemeResource SystemControlChromeLowAcrylicWindowBrush}">

Просмотреть файл

@ -54,9 +54,7 @@
<ItemGroup>
<PackageReference Include="System.Reactive" Version="4.1.2" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.2" />
<PackageReference Include="ReactiveUI.AndroidSupport">
<Version>9.5.1</Version>
</PackageReference>
<PackageReference Include="ReactiveUI.AndroidSupport" Version="9.8.23"/>
<PackageReference Include="Xamarin.Forms" Version="3.4.0.1008975" />
<PackageReference Include="Xamarin.Android.Support.Design" Version="28.0.0" />
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat" Version="28.0.0" />

Просмотреть файл

@ -10,7 +10,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ReactiveUI.XamForms" Version="9.5.1" />
<PackageReference Include="ReactiveUI.XamForms" Version="9.8.23" />
<PackageReference Include="Xamarin.Forms" Version="3.4.0.1008975" />
<PackageReference Include="Xam.Plugin.Iconize" Version="3.4.0.103" />
<PackageReference Include="Xam.Plugin.Iconize.FontAwesome" Version="3.4.0.103" />

Просмотреть файл

@ -9,8 +9,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ReactiveUI" Version="9.5.1" />
<PackageReference Include="ReactiveUI.Fody" Version="9.5.1" />
<PackageReference Include="ReactiveUI" Version="9.8.23" />
<PackageReference Include="ReactiveUI.Fody" Version="9.8.23" />
<PackageReference Include="DynamicData" Version="6.7.1.2534" />
</ItemGroup>

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Weavers>
<ReactiveUI />
<?xml version="1.0" encoding="utf-8"?>
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ReactiveUI />
</Weavers>

Просмотреть файл

@ -18,6 +18,8 @@ namespace Camelotia.Presentation.Interfaces
ICommand UploadToCurrentPath { get; }
ICommand DeleteSelectedFile { get; }
ICommand UnselectFile { get; }
ICommand Refresh { get; }
@ -37,6 +39,8 @@ namespace Camelotia.Presentation.Interfaces
bool CanLogout { get; }
int RefreshingIn { get; }
string CurrentPath { get; }
string Description { get; }

Просмотреть файл

@ -1,13 +1,13 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Input;
using System.Collections.Generic;
using System.Reactive;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Reactive.Disposables;
using System.Reactive.Threading.Tasks;
using System.Windows.Input;
using Camelotia.Presentation.Interfaces;
using Camelotia.Services.Interfaces;
using Camelotia.Services.Models;
@ -30,6 +30,7 @@ namespace Camelotia.Presentation.ViewModels
private readonly ObservableAsPropertyHelper<bool> _isLoading;
private readonly ObservableAsPropertyHelper<bool> _canLogout;
private readonly ObservableAsPropertyHelper<bool> _isReady;
private readonly ReactiveCommand<Unit, Unit> _unselectFile;
private readonly ReactiveCommand<Unit, string> _back;
private readonly ReactiveCommand<Unit, string> _open;
private readonly ReactiveCommand<Unit, Unit> _logout;
@ -53,6 +54,7 @@ namespace Camelotia.Presentation.ViewModels
.ThenBy(file => file.Name)
.ToList())
.StartWithEmpty()
.Where(files => Files == null || !files.SequenceEqual(Files))
.ToProperty(this, x => x.Files, scheduler: currentThread);
_isLoading = _refresh
@ -98,7 +100,7 @@ namespace Camelotia.Presentation.ViewModels
_isCurrentPathEmpty = this
.WhenAnyValue(x => x.Files)
.Skip(2)
.Skip(1)
.Where(files => files != null)
.Select(files => !files.Any())
.ToProperty(this, x => x.IsCurrentPathEmpty, scheduler: currentThread);
@ -112,7 +114,7 @@ namespace Camelotia.Presentation.ViewModels
var canUploadToCurrentPath = this
.WhenAnyValue(x => x.CurrentPath)
.Select(path => path != null)
.DistinctUntilChanged();
.CombineLatest(_refresh.IsExecuting, (up, loading) => up && !loading);
_uploadToCurrentPath = ReactiveCommand.CreateFromObservable(
() => Observable
@ -128,7 +130,7 @@ namespace Camelotia.Presentation.ViewModels
var canDownloadSelectedFile = this
.WhenAnyValue(x => x.SelectedFile)
.Select(file => file != null && !file.IsFolder)
.DistinctUntilChanged();
.CombineLatest(_refresh.IsExecuting, (down, loading) => down && !loading);
_downloadSelectedFile = ReactiveCommand.CreateFromObservable(
() => Observable
@ -144,15 +146,6 @@ namespace Camelotia.Presentation.ViewModels
.Merge(_downloadSelectedFile.ThrownExceptions)
.Merge(_refresh.ThrownExceptions)
.Subscribe(Console.WriteLine);
this.WhenAnyValue(x => x.SelectedFile)
.Where(file => file != null && file.IsFolder)
.Buffer(2, 1)
.Select(files => (files.First().Path, files.Last().Path))
.DistinctUntilChanged()
.Where(x => x.Item1 == x.Item2)
.Select(ignore => Unit.Default)
.InvokeCommand(_open);
var isAuthEnabled = provider.SupportsDirectAuth || provider.SupportsOAuth;
var canLogout = provider
@ -167,13 +160,23 @@ namespace Camelotia.Presentation.ViewModels
var canDeleteSelection = this
.WhenAnyValue(x => x.SelectedFile)
.Select(file => file != null && !file.IsFolder);
.Select(file => file != null && !file.IsFolder)
.CombineLatest(_refresh.IsExecuting, (del, loading) => del && !loading);
_deleteSelectedFile = ReactiveCommand.CreateFromTask(
() => provider.Delete(SelectedFile),
canDeleteSelection);
_deleteSelectedFile.InvokeCommand(Refresh);
var canUnselectFile = this
.WhenAnyValue(x => x.SelectedFile)
.Select(selection => selection != null)
.CombineLatest(_refresh.IsExecuting, (sel, loading) => sel && !loading);
_unselectFile = ReactiveCommand.Create(
() => { SelectedFile = null; },
canUnselectFile);
Auth = authViewModel;
Activator = new ViewModelActivator();
@ -184,6 +187,30 @@ namespace Camelotia.Presentation.ViewModels
.Select(ignore => Unit.Default)
.InvokeCommand(_refresh)
.DisposeWith(disposable);
var interval = TimeSpan.FromSeconds(1);
var tick = Observable
.Timer(interval, interval)
.Select(value => Unit.Default)
.ObserveOn(mainThread);
tick.Select(unit => RefreshingIn - 1)
.Where(value => value >= 0)
.Subscribe(x => RefreshingIn = x)
.DisposeWith(disposable);
this.WhenAnyValue(x => x.RefreshingIn)
.Skip(1)
.Where(refreshing => refreshing == 0)
.Select(value => Unit.Default)
.InvokeCommand(_refresh)
.DisposeWith(disposable);
const int refreshPeriod = 30;
_refresh.Select(results => refreshPeriod)
.StartWith(refreshPeriod)
.Subscribe(x => RefreshingIn = x)
.DisposeWith(disposable);
});
}
@ -193,6 +220,8 @@ namespace Camelotia.Presentation.ViewModels
[Reactive] public FileModel SelectedFile { get; set; }
[Reactive] public int RefreshingIn { get; private set; }
public string CurrentPath => _currentPath?.Value ?? _provider.InitialPath;
public ICommand DownloadSelectedFile => _downloadSelectedFile;
@ -203,10 +232,12 @@ namespace Camelotia.Presentation.ViewModels
public bool IsCurrentPathEmpty => _isCurrentPathEmpty.Value;
public IEnumerable<FileModel> Files => _files.Value;
public IEnumerable<FileModel> Files => _files?.Value;
public string Description => _provider.Description;
public ICommand UnselectFile => _unselectFile;
public bool CanLogout => _canLogout.Value;
public bool IsLoading => _isLoading.Value;

Просмотреть файл

@ -2,6 +2,16 @@ namespace Camelotia.Services.Models
{
public sealed class FileModel
{
public string Name { get; }
public string Path { get; }
public bool IsFolder { get; }
public bool IsFile => !IsFolder;
public string Size { get; }
public FileModel(string name, string path, bool isFolder, string size)
{
Name = name;
@ -9,13 +19,18 @@ namespace Camelotia.Services.Models
IsFolder = isFolder;
Size = size;
}
public string Name { get; }
public string Path { get; }
public override int GetHashCode() => (Name, Path, IsFolder, Size).GetHashCode();
public bool IsFolder { get; }
public string Size { get; }
public override bool Equals(object obj)
{
var file = obj as FileModel;
return
file != null &&
file.Name == Name &&
file.Path == Path &&
file.IsFolder == IsFolder &&
file.Size == Size;
}
}
}

Просмотреть файл

@ -1,6 +1,6 @@
[![Build Status](https://worldbeater.visualstudio.com/Camelotia/_apis/build/status/Camelotia-CI)](https://worldbeater.visualstudio.com/Camelotia/_build/latest?definitionId=1) [![Pull Requests](https://img.shields.io/github/issues-pr/worldbeater/camelotia.svg)](https://github.com/worldbeater/Camelotia/pulls) [![Issues](https://img.shields.io/github/issues/worldbeater/camelotia.svg)](https://github.com/worldbeater/Camelotia/issues) ![License](https://img.shields.io/github/license/worldbeater/camelotia.svg) ![Size](https://img.shields.io/github/repo-size/worldbeater/camelotia.svg)
The app runs on Windows, Linux, MacOS, XBox, Surface Hub and HoloLens.
The app runs on Windows, Linux, MacOS, XBox, Surface Hub and HoloLens. Built with [ReactiveUI](https://github.com/reactiveui/ReactiveUI).
## Compiling Avalonia app

Двоичные данные
UiAvalonia.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 92 KiB

После

Ширина:  |  Высота:  |  Размер: 95 KiB

Двоичные данные
UiWindows.jpg

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 117 KiB

После

Ширина:  |  Высота:  |  Размер: 116 KiB