Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion paket.lock
Original file line number Diff line number Diff line change
Expand Up @@ -112,5 +112,5 @@ NUGET
GITHUB
remote: fsharp/FAKE
specs:
modules/Octokit/Octokit.fsx (3f9b431915b7a568217d257f50693a3fdc1c7ebc)
modules/Octokit/Octokit.fsx (ac46f8ba9cc11bb6e8d02197720697c9e258c0d3)
Octokit
38 changes: 18 additions & 20 deletions src/Paket.VisualStudio/Commands/AddPackageProcess.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
using System.Reactive;
using System.Reactive.Disposables;
using Microsoft.FSharp.Control;
using Microsoft.FSharp.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
Expand All @@ -16,34 +13,35 @@ namespace Paket.VisualStudio.Commands
{
public class AddPackageProcess
{
public static Task<string[]> SearchPackagesByName(string name)
public static Task<string[]> SearchPackagesByName(string search, CancellationToken ct)
{
return FSharpAsync.StartAsTask(NuGetV3.FindPackages(FSharpOption<Paket.Utils.Auth>.None, Constants.DefaultNugetStream,
name, 1000),
//TODO: this should probably return a success/failure type to indicate whether the search was successful. (Like lack of internet, nuget down)
return FSharpAsync.StartAsTask(NuGetV3.FindPackages(FSharpOption<Paket.Utils.Auth>.None, Constants.DefaultNugetStream,
search, 1000),
FSharpOption<TaskCreationOptions>.None,
FSharpOption<CancellationToken>.None);

FSharpOption<CancellationToken>.Some(ct));
}

public static void ShowAddPackageDialog(string selectedFileName, string projectGuid = null)
{
var dependenciesFile = Paket.Dependencies.Locate(selectedFileName);

var secondWindow = new AddPackage();
//TODO: Use interfaces?

Func<string, CancellationToken, Task<string[]>> findPackages = (search, ct) =>
//Create observable paket trace
var paketTraceObs = Observable.Create<string>(observer =>
{
//TODO: this should probably return a success/failure type to indicate whether the search was successful. (Like lack of internet, nuget down)
return FSharpAsync.StartAsTask(NuGetV3.FindPackages(FSharpOption<Paket.Utils.Auth>.None, Constants.DefaultNugetStream,
search, 1000),
FSharpOption<TaskCreationOptions>.None,
FSharpOption<CancellationToken>.Some(ct));
};
Paket.Logging.RegisterTraceFunction(observer.OnNext);
return Disposable.Create(() =>
{
Paket.Logging.RemoveTraceFunction(observer.OnNext);
});
});

Action<NugetResult> addPackageToDependencies = result =>
{
var packageName = result.PackageName;
secondWindow.Close();
//secondWindow.Close();
Application.DoEvents();

if (projectGuid != null)
Expand All @@ -56,8 +54,8 @@ public static void ShowAddPackageDialog(string selectedFileName, string projectG
else
dependenciesFile.Add(packageName, "", false, false, false, true);
};

secondWindow.ViewModel = new AddPackageViewModel(findPackages,addPackageToDependencies);
//TODO: Use interfaces?
secondWindow.ViewModel = new AddPackageViewModel(SearchPackagesByName, addPackageToDependencies, paketTraceObs);
secondWindow.ShowDialog();
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Paket.VisualStudio/Commands/PackageGui/AddPackage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
</ListBox.ItemTemplate>

</ListBox>
<TextBlock Visibility="Hidden" FontSize="20" Foreground="Red" x:Name="Errors" Grid.Row="2"></TextBlock>
<TextBlock Visibility="Visible" FontSize="20" Foreground="Red" x:Name="Errors" Grid.Row="2"></TextBlock>
</Grid>
<StackPanel Grid.Column="1">
<Button x:Name="AddPackageButton" Margin="20,20,20,20" Padding="5,5,5,5">Add Package</Button>
Expand Down
80 changes: 70 additions & 10 deletions src/Paket.VisualStudio/Commands/PackageGui/AddPackage.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using System.Reactive.Concurrency;
using System.Text;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using ReactiveUI;

namespace Paket.VisualStudio.Commands.PackageGui
Expand All @@ -21,17 +17,75 @@ namespace Paket.VisualStudio.Commands.PackageGui
/// </summary>
public partial class AddPackage : Window, IViewFor<IAddPackageViewModel>
{
private CompositeDisposable _compositeDisposable;

public AddPackage()
{
_compositeDisposable = new CompositeDisposable();
InitializeComponent();

this.Events().Loaded.Subscribe(_ =>
this.Events().Loaded.Subscribe(__ =>
{
//Bindings
this.OneWayBind(ViewModel, vm => vm.NugetResults, v => v.NugetResults.ItemsSource);
this.Bind(ViewModel, vm => vm.SearchText, v => v.SearchTextBox.Text);
this.Bind(ViewModel, vm => vm.SelectedPackage, v => v.NugetResults.SelectedItem);
this.BindCommand(ViewModel, x => x.AddPackage, v => v.AddPackageButton);

var dialog = new PaketOutputDialog();
//TODO: These visual states should be handled more elegantly
//Open an output dialog window when adding a new package executes
ViewModel.AddPackage
.IsExecuting
.Where(isExecuting => isExecuting)
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ =>
{
dialog.Show();
dialog.ProgressBar.IsIndeterminate = true;
dialog.DialogBox.Clear();
})
.AddTo(_compositeDisposable);

ViewModel.AddPackage
.Where(_ => dialog.Visibility == Visibility.Visible)
.ObserveOn(RxApp.MainThreadScheduler)
//OnNext gets called when the AddPackage command finishes
.Subscribe(_ =>
{
dialog.ProgressBar.IsIndeterminate = false;
dialog.ProgressBar.Value = 100;
//Close the dialog after 5 seconds after adding a package executes
//TODO: Should give use visual cue this will happen
Observable.Timer(TimeSpan.FromSeconds(5))
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(___ => dialog.Hide())
.AddTo(_compositeDisposable);
},
_ =>
{
dialog.ProgressBar.IsIndeterminate = false;
dialog.ProgressBar.Value = 100;
dialog.ProgressBar.Foreground = Brushes.Red;
})
.AddTo(_compositeDisposable);







//Listen to the paket trace and put it in the dialog box
ViewModel.PaketTrace
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(text =>
{
dialog.DialogBox.Text += string.Format("{0}{1}", text, Environment.NewLine);
dialog.DialogBox.ScrollToEnd();
})
.AddTo(_compositeDisposable);

var disconnectHandler = UserError.RegisterHandler(async error =>
{
// We don't know what thread a UserError can be thrown from, we usually
Expand All @@ -46,12 +100,17 @@ public AddPackage()
await Task.Delay(8000);
Errors.Text = string.Empty;
Errors.Visibility = Visibility.Hidden;

});

return RecoveryOptionResult.CancelOperation;
});
});

this.Events().Closed.Subscribe(__ =>
{
_compositeDisposable.Dispose();
});
}

public IAddPackageViewModel ViewModel { get; set; }
Expand All @@ -74,6 +133,7 @@ public DesignTimeViewModel()
public NugetResult SelectedPackage { get; set; }
public IEnumerable<NugetResult> NugetResults { get; private set; }
public ICommand SearchNuget { get; private set; }
public ICommand AddPackage { get; private set; }
public ReactiveCommand<Unit> AddPackage { get; private set; }
public IObservable<string> PaketTrace { get; private set; }
}
}
29 changes: 18 additions & 11 deletions src/Paket.VisualStudio/Commands/PackageGui/AddPackageViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading;
using System.Windows.Input;
using Microsoft.FSharp.Control;
using Microsoft.FSharp.Core;
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reactive.Linq;
using System.Threading.Tasks;

Expand All @@ -23,7 +19,8 @@ public interface IAddPackageViewModel
IEnumerable<NugetResult> NugetResults { get; }

ICommand SearchNuget { get; }
ICommand AddPackage { get; }
ReactiveCommand<System.Reactive.Unit> AddPackage { get; }
IObservable<string> PaketTrace { get; }
}

public class NugetResult
Expand All @@ -34,6 +31,12 @@ public class NugetResult
public class AddPackageViewModel : ReactiveObject, IAddPackageViewModel
{
private readonly Func<string, CancellationToken, Task<string[]>> _findPackageCallback;
private readonly IObservable<string> _paketTraceFunObservable;

public IObservable<string> PaketTrace
{
get { return _paketTraceFunObservable; }
}
string _searchText;
public string SearchText
{
Expand Down Expand Up @@ -64,14 +67,16 @@ public IEnumerable<NugetResult> NugetResults
private ReactiveCommand<IEnumerable<NugetResult>> _searchNuget;
public ICommand SearchNuget { get { return _searchNuget; } }

private ReactiveCommand<object> _addPackage;
public ICommand AddPackage { get { return _addPackage; } }

public ReactiveCommand<System.Reactive.Unit> AddPackage { get; private set; }

public AddPackageViewModel(
Func<string, CancellationToken, Task<string[]>> findPackageCallback,
Action<NugetResult> addPackageCallback)
Action<NugetResult> addPackageCallback,
IObservable<string> paketTraceFunObservable)
{
_findPackageCallback = findPackageCallback;
_paketTraceFunObservable = paketTraceFunObservable;
_searchNuget = ReactiveCommand.CreateAsyncTask((_, cancellationToken) => SearchPackagesByName(SearchText, cancellationToken));

//TODO: Localization
Expand All @@ -83,8 +88,10 @@ public AddPackageViewModel(
.Subscribe();
_searchNuget.ToProperty(this, x => x.NugetResults, out _results);

_addPackage = ReactiveCommand.Create(this.WhenAnyValue(x => x.SelectedPackage).Select(x => x != null));
_addPackage.Subscribe(_ => addPackageCallback(SelectedPackage));
AddPackage = ReactiveCommand.CreateAsyncTask(
this.WhenAnyValue(x => x.SelectedPackage).Select(x => x != null),
_ => Task.Run(() => addPackageCallback(SelectedPackage)));

this.ObservableForProperty(x => x.SearchText)
.Where(x => !string.IsNullOrEmpty(SearchText))
.Throttle(TimeSpan.FromMilliseconds(250))
Expand Down
34 changes: 34 additions & 0 deletions src/Paket.VisualStudio/Commands/PackageGui/PaketOutputDialog.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<Window x:Class="Paket.VisualStudio.Commands.PackageGui.PaketOutputDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="PaketOutputDialog" Height="300" Width="500">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ProgressBar
x:Name="ProgressBar"
Padding="10,10,10,10"
Margin="10,10,10,10"
IsIndeterminate="True"
Minimum="0"
Maximum="100"
Height="20" />
<TextBox
x:Name="DialogBox"
Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
TextWrapping="Wrap"
IsReadOnly="True"
AcceptsReturn="True"
VerticalScrollBarVisibility="Visible" />



</Grid>
</Window>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace Paket.VisualStudio.Commands.PackageGui
{
/// <summary>
/// Interaction logic for PaketOutputDialog.xaml
/// </summary>
public partial class PaketOutputDialog : Window
{
public PaketOutputDialog()
{
InitializeComponent();
}
}
}
8 changes: 8 additions & 0 deletions src/Paket.VisualStudio/Paket.VisualStudio.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@
<DependentUpon>AddPackage.xaml</DependentUpon>
</Compile>
<Compile Include="Commands\PackageGui\AddPackageViewModel.cs" />
<Compile Include="Utils\DisposableHelpers.cs" />
<Compile Include="Commands\PackageGui\PaketOutputDialog.xaml.cs">
<DependentUpon>PaketOutputDialog.xaml</DependentUpon>
</Compile>
<Compile Include="EditorExtensions\CommandTargetBase.cs" />
<Compile Include="EditorExtensions\CommentCommandTarget.cs" />
<Compile Include="EditorExtensions\Disposable.cs" />
Expand Down Expand Up @@ -258,6 +262,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Commands\PackageGui\PaketOutputDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.0' Or $(TargetFrameworkVersion) == 'v4.5' Or $(TargetFrameworkVersion) == 'v4.5.1' Or $(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6')">
Expand Down
19 changes: 19 additions & 0 deletions src/Paket.VisualStudio/Utils/DisposableHelpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Reactive.Disposables;

namespace Paket.VisualStudio.Commands.PackageGui
{
public static class DisposableHelpers
{
/// <summary>
/// Helper function to add IDisposables to a composible disposable.
/// This allows for easy chaining when using Reactive Extensions.
/// </summary>
/// <param name="disposable"></param>
/// <param name="compositeDisposable"></param>
public static void AddTo(this IDisposable disposable, CompositeDisposable compositeDisposable)
{
compositeDisposable.Add(disposable);
}
}
}