Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit cfc8f6c

Browse files
authored
Merge pull request #934 from github/grokys/pr-details-busy
Display indeterminate progress bar when updating PR details view.
2 parents f778c6c + cf0846c commit cfc8f6c

File tree

13 files changed

+123
-54
lines changed

13 files changed

+123
-54
lines changed

src/GitHub.App/SampleData/PullRequestDetailViewModelDesigner.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Diagnostics.CodeAnalysis;
34
using System.Reactive;
45
using System.Threading.Tasks;
@@ -27,6 +28,8 @@ public class PullRequestUpdateStateDesigner : IPullRequestUpdateState
2728
[ExcludeFromCodeCoverage]
2829
public class PullRequestDetailViewModelDesigner : PanePageViewModelBase, IPullRequestDetailViewModel
2930
{
31+
private List<IPullRequestChangeNode> changedFilesTree;
32+
3033
public PullRequestDetailViewModelDesigner()
3134
{
3235
var repoPath = @"C:\Repo";
@@ -63,18 +66,19 @@ public PullRequestDetailViewModelDesigner()
6366
modelsDir.Files.Add(oldBranchModel);
6467
gitHubDir.Directories.Add(modelsDir);
6568

66-
ChangedFilesTree = new ReactiveList<IPullRequestChangeNode>();
67-
ChangedFilesTree.Add(gitHubDir);
69+
changedFilesTree = new List<IPullRequestChangeNode>();
70+
changedFilesTree.Add(gitHubDir);
6871
}
6972

7073
public IPullRequestModel Model { get; }
7174
public string SourceBranchDisplayName { get; set; }
7275
public string TargetBranchDisplayName { get; set; }
76+
public bool IsLoading { get; }
7377
public bool IsBusy { get; }
7478
public bool IsCheckedOut { get; }
7579
public bool IsFromFork { get; }
7680
public string Body { get; }
77-
public IReactiveList<IPullRequestChangeNode> ChangedFilesTree { get; }
81+
public IReadOnlyList<IPullRequestChangeNode> ChangedFilesTree => changedFilesTree;
7882
public IPullRequestCheckoutState CheckoutState { get; set; }
7983
public IPullRequestUpdateState UpdateState { get; set; }
8084
public string OperationError { get; set; }

src/GitHub.App/SampleData/SampleViewModels.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -374,11 +374,6 @@ public bool FilterTextIsEnabled
374374

375375
public new string Title { get { return "Clone a GitHub Repository"; } }
376376

377-
public bool IsLoading
378-
{
379-
get { return false; }
380-
}
381-
382377
public IReactiveCommand<IReadOnlyList<IRemoteRepositoryModel>> LoadRepositoriesCommand
383378
{
384379
get;

src/GitHub.App/ViewModels/PullRequestDetailViewModel.cs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace GitHub.ViewModels
2525
[ExportViewModel(ViewType = UIViewType.PRDetail)]
2626
[PartCreationPolicy(CreationPolicy.NonShared)]
2727
[NullGuard(ValidationFlags.None)]
28-
public class PullRequestDetailViewModel : PanePageViewModelBase, IPullRequestDetailViewModel, IHasBusy
28+
public class PullRequestDetailViewModel : PanePageViewModelBase, IPullRequestDetailViewModel
2929
{
3030
readonly ILocalRepositoryModel repository;
3131
readonly IModelService modelService;
@@ -35,10 +35,12 @@ public class PullRequestDetailViewModel : PanePageViewModelBase, IPullRequestDet
3535
string sourceBranchDisplayName;
3636
string targetBranchDisplayName;
3737
string body;
38+
IReadOnlyList<IPullRequestChangeNode> changedFilesTree;
3839
IPullRequestCheckoutState checkoutState;
3940
IPullRequestUpdateState updateState;
4041
string operationError;
4142
bool isBusy;
43+
bool isLoading;
4244
bool isCheckedOut;
4345
bool isFromFork;
4446
bool isInCheckout;
@@ -147,7 +149,7 @@ public string TargetBranchDisplayName
147149
}
148150

149151
/// <summary>
150-
/// Gets a value indicating whether the view model is loading.
152+
/// Gets a value indicating whether the view model is updating.
151153
/// </summary>
152154
public bool IsBusy
153155
{
@@ -163,6 +165,15 @@ public bool IsCheckedOut
163165
private set { this.RaiseAndSetIfChanged(ref isCheckedOut, value); }
164166
}
165167

168+
/// <summary>
169+
/// Gets a value indicating whether the view model is loading.
170+
/// </summary>
171+
public bool IsLoading
172+
{
173+
get { return isLoading; }
174+
private set { this.RaiseAndSetIfChanged(ref isLoading, value); }
175+
}
176+
166177
/// <summary>
167178
/// Gets a value indicating whether the pull request comes from a fork.
168179
/// </summary>
@@ -212,7 +223,11 @@ public string OperationError
212223
/// <summary>
213224
/// Gets the changed files as a tree.
214225
/// </summary>
215-
public IReactiveList<IPullRequestChangeNode> ChangedFilesTree { get; } = new ReactiveList<IPullRequestChangeNode>();
226+
public IReadOnlyList<IPullRequestChangeNode> ChangedFilesTree
227+
{
228+
get { return changedFilesTree; }
229+
private set { this.RaiseAndSetIfChanged(ref changedFilesTree, value); }
230+
}
216231

217232
/// <summary>
218233
/// Gets a command that checks out the pull request locally.
@@ -252,7 +267,10 @@ public override void Initialize([AllowNull] ViewWithData data)
252267
{
253268
var prNumber = data?.Data != null ? (int)data.Data : Model.Number;
254269

255-
IsBusy = true;
270+
if (Model == null)
271+
IsLoading = true;
272+
else
273+
IsBusy = true;
256274

257275
OperationError = null;
258276
modelService.GetPullRequest(repository, prNumber)
@@ -276,15 +294,8 @@ public async Task Load(IPullRequestModel pullRequest)
276294
TargetBranchDisplayName = GetBranchDisplayName(IsFromFork, pullRequest.Base.Label);
277295
Body = !string.IsNullOrWhiteSpace(pullRequest.Body) ? pullRequest.Body : Resources.NoDescriptionProvidedMarkdown;
278296

279-
ChangedFilesTree.Clear();
280-
281-
var treeChanges = await pullRequestsService.GetTreeChanges(repository, pullRequest);
282-
283-
// WPF doesn't support AddRange here so iterate through the changes.
284-
foreach (var change in CreateChangedFilesTree(pullRequest, treeChanges).Children)
285-
{
286-
ChangedFilesTree.Add(change);
287-
}
297+
var changes = await pullRequestsService.GetTreeChanges(repository, pullRequest);
298+
ChangedFilesTree = CreateChangedFilesTree(pullRequest, changes).Children.ToList();
288299

289300
var localBranches = await pullRequestsService.GetLocalBranches(repository, pullRequest).ToList();
290301

@@ -350,7 +361,7 @@ public async Task Load(IPullRequestModel pullRequest)
350361
UpdateState = null;
351362
}
352363

353-
IsBusy = false;
364+
IsLoading = IsBusy = false;
354365

355366
if (!isInCheckout)
356367
{

src/GitHub.App/ViewModels/RepositoryCloneViewModel.cs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ public class RepositoryCloneViewModel : DialogViewModelBase, IRepositoryCloneVie
3535
readonly IRepositoryHost repositoryHost;
3636
readonly IOperatingSystem operatingSystem;
3737
readonly ReactiveCommand<object> browseForDirectoryCommand = ReactiveCommand.Create();
38-
bool isLoading;
3938
bool noRepositoriesFound;
4039
readonly ObservableAsPropertyHelper<bool> canClone;
4140
string baseRepositoryPath;
@@ -66,13 +65,13 @@ public RepositoryCloneViewModel(
6665
repositories.Filter = FilterRepository;
6766
repositories.NewerComparer = OrderedComparer<IRemoteRepositoryModel>.OrderByDescending(x => x.UpdatedAt).Compare;
6867

69-
filterTextIsEnabled = this.WhenAny(x => x.IsLoading,
68+
filterTextIsEnabled = this.WhenAny(x => x.IsBusy,
7069
loading => loading.Value || repositories.UnfilteredCount > 0 && !LoadingFailed)
7170
.ToProperty(this, x => x.FilterTextIsEnabled);
7271

7372
this.WhenAny(
7473
x => x.repositories.UnfilteredCount,
75-
x => x.IsLoading,
74+
x => x.IsBusy,
7675
x => x.LoadingFailed,
7776
(unfilteredCount, loading, failed) =>
7877
{
@@ -124,17 +123,17 @@ public override void Initialize([AllowNull] ViewWithData data)
124123
{
125124
base.Initialize(data);
126125

127-
IsLoading = true;
126+
IsBusy = true;
128127
repositoryHost.ModelService.GetRepositories(repositories);
129128
repositories.OriginalCompleted.Subscribe(
130129
_ => { }
131130
, ex =>
132131
{
133132
LoadingFailed = true;
134-
IsLoading = false;
133+
IsBusy = false;
135134
log.Error("Error while loading repositories", ex);
136135
},
137-
() => IsLoading = false
136+
() => IsBusy = false
138137
);
139138
repositories.Subscribe();
140139
}
@@ -244,12 +243,6 @@ public string FilterText
244243
set { this.RaiseAndSetIfChanged(ref filterText, value); }
245244
}
246245

247-
public bool IsLoading
248-
{
249-
get { return isLoading; }
250-
private set { this.RaiseAndSetIfChanged(ref isLoading, value); }
251-
}
252-
253246
public bool LoadingFailed
254247
{
255248
get { return loadingFailed; }

src/GitHub.Exports.Reactive/ViewModels/IPullRequestDetailViewModel.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Reactive;
34
using System.Threading.Tasks;
45
using GitHub.Models;
@@ -62,7 +63,7 @@ public interface IPullRequestUpdateState
6263
/// <summary>
6364
/// Represents a view model for displaying details of a pull request.
6465
/// </summary>
65-
public interface IPullRequestDetailViewModel : IViewModel, IHasBusy
66+
public interface IPullRequestDetailViewModel : IViewModel, IHasLoading, IHasBusy
6667
{
6768
/// <summary>
6869
/// Gets the underlying pull request model.
@@ -97,7 +98,7 @@ public interface IPullRequestDetailViewModel : IViewModel, IHasBusy
9798
/// <summary>
9899
/// Gets the changed files as a tree.
99100
/// </summary>
100-
IReactiveList<IPullRequestChangeNode> ChangedFilesTree { get; }
101+
IReadOnlyList<IPullRequestChangeNode> ChangedFilesTree { get; }
101102

102103
/// <summary>
103104
/// Gets the state associated with the <see cref="Checkout"/> command.

src/GitHub.Exports.Reactive/ViewModels/IRepositoryCloneViewModel.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,6 @@ public interface IRepositoryCloneViewModel : IBaseCloneViewModel, IRepositoryCre
1919

2020
bool FilterTextIsEnabled { get; }
2121

22-
/// <summary>
23-
/// Whether or not we are currently loading repositories.
24-
/// </summary>
25-
bool IsLoading { get; }
26-
2722
/// <summary>
2823
/// If true, then we failed to load the repositories.
2924
/// </summary>

src/GitHub.Exports/GitHub.Exports.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129
<Reference Include="WindowsBase" />
130130
</ItemGroup>
131131
<ItemGroup>
132+
<Compile Include="ViewModels\IHasLoading.cs" />
132133
<Compile Include="ViewModels\IPanePageViewModel.cs" />
133134
<Compile Include="ViewModels\IViewModel.cs" />
134135
<None Include="..\..\script\Key.snk" Condition="$(Buildtype) == 'Internal'">

src/GitHub.Exports/ViewModels/IHasBusy.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ namespace GitHub.ViewModels
55
/// <summary>
66
/// Interface for view models that have a busy state.
77
/// </summary>
8+
/// <remarks>
9+
/// <see cref="IHasLoading"/> is similar to <see cref="IHasBusy"/> but they represent
10+
/// different states:
11+
/// - When <see cref="IHasLoading.IsLoading"/> is true: There is no data to display.
12+
/// - When <see cref="IHasBusy.IsBusy"/> is true: There is data to display but that data is
13+
/// being updated or is in the process of being loaded.
14+
/// </remarks>
815
public interface IHasBusy
916
{
1017
bool IsBusy { get; }
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
3+
namespace GitHub.ViewModels
4+
{
5+
/// <summary>
6+
/// Interface for view models that have a busy state.
7+
/// </summary>
8+
/// <remarks>
9+
/// <see cref="IHasLoading"/> is similar to <see cref="IHasBusy"/> but they represent
10+
/// different states:
11+
/// - When <see cref="IHasLoading.IsLoading"/> is true: There is no data to display.
12+
/// - When <see cref="IHasBusy.IsBusy"/> is true: There is data to display but that data is
13+
/// being updated or is in the process of being loaded.
14+
/// </remarks>
15+
public interface IHasLoading
16+
{
17+
bool IsLoading { get; }
18+
}
19+
}

src/GitHub.UI.Reactive/Assets/Controls/BusyStateView.xaml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,29 @@
99
<Setter.Value>
1010
<ControlTemplate TargetType="{x:Type local:BusyStateView}">
1111
<Grid>
12+
<Grid.RowDefinitions>
13+
<RowDefinition Height="Auto"/>
14+
<RowDefinition Height="*"/>
15+
</Grid.RowDefinitions>
16+
1217
<Grid.Resources>
1318
<BooleanToVisibilityConverter x:Key="b2v"/>
1419
</Grid.Resources>
15-
20+
21+
<ui:GitHubProgressBar Foreground="{DynamicResource GitHubAccentBrush}"
22+
IsIndeterminate="True"
23+
Style="{DynamicResource GitHubProgressBar}"
24+
Visibility="{TemplateBinding IsBusy, Converter={ui:BooleanToHiddenVisibilityConverter}}"/>
25+
1626
<c:Spinner Name="spinner"
27+
Grid.Row="1"
1728
Width="48"
1829
Height="48"
1930
HorizontalAlignment="Center"
2031
VerticalAlignment="Center"
21-
Visibility="{TemplateBinding IsBusy, Converter={ui:BooleanToHiddenVisibilityConverter}}"/>
22-
<ContentPresenter Visibility="{TemplateBinding IsBusy, Converter={ui:BooleanToInverseHiddenVisibilityConverter}}"/>
32+
Visibility="{TemplateBinding IsLoading, Converter={ui:BooleanToHiddenVisibilityConverter}}"/>
33+
<ContentPresenter Grid.Row="1"
34+
Visibility="{TemplateBinding IsLoading, Converter={ui:BooleanToInverseHiddenVisibilityConverter}}"/>
2335
</Grid>
2436
</ControlTemplate>
2537
</Setter.Value>

0 commit comments

Comments
 (0)