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

Commit 9ee5f0e

Browse files
committed
Display error messages in GitHubPane.
1 parent 22c8345 commit 9ee5f0e

File tree

8 files changed

+103
-19
lines changed

8 files changed

+103
-19
lines changed

src/GitHub.App/ViewModels/GitHubPane/GitHubPaneViewModel.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public sealed class GitHubPaneViewModel : ViewModelBase, IGitHubPaneViewModel, I
4040
readonly INotAGitHubRepositoryViewModel notAGitHubRepository;
4141
readonly INotAGitRepositoryViewModel notAGitRepository;
4242
readonly SemaphoreSlim navigating = new SemaphoreSlim(1);
43+
readonly ObservableAsPropertyHelper<ContentOverride> contentOverride;
4344
readonly ObservableAsPropertyHelper<bool> isSearchEnabled;
4445
readonly ObservableAsPropertyHelper<string> title;
4546
readonly ReactiveCommand<Unit> refresh;
@@ -90,6 +91,17 @@ public GitHubPaneViewModel(
9091
navigator.WhenAnyValue(x => x.Content))
9192
.Select(x => x[0] == navigator ? x[1] as IPanePageViewModel : null);
9293

94+
contentOverride = currentPage
95+
.SelectMany(x => x?.WhenAnyValue(y => y.IsLoading, y => y.Error) ??
96+
Observable.Return<Tuple<bool, Exception>>(null))
97+
.Select(x =>
98+
{
99+
if (x == null || x.Item1) return ContentOverride.Spinner;
100+
else if (x.Item2 != null) return ContentOverride.Error;
101+
else return ContentOverride.None;
102+
})
103+
.ToProperty(this, x => x.ContentOverride);
104+
93105
title = currentPage
94106
.SelectMany(x => x?.WhenAnyValue(y => y.Title) ?? Observable.Return<string>(null))
95107
.Select(x => x ?? "GitHub")
@@ -106,6 +118,7 @@ public GitHubPaneViewModel(
106118
(loading, busy) => !loading && !busy)
107119
?? Observable.Return(false)),
108120
_ => navigator.Content.Refresh());
121+
refresh.ThrownExceptions.Subscribe();
109122

110123
showPullRequests = ReactiveCommand.CreateAsyncTask(
111124
this.WhenAny(x => x.Content, x => x.Value == navigator),
@@ -141,6 +154,9 @@ public IViewModel Content
141154
private set { this.RaiseAndSetIfChanged(ref content, value); }
142155
}
143156

157+
/// <inheritdoc/>
158+
public ContentOverride ContentOverride => contentOverride.Value;
159+
144160
/// <inheritdoc/>
145161
public bool IsSearchEnabled => isSearchEnabled.Value;
146162

src/GitHub.App/ViewModels/GitHubPane/PanePageViewModelBase.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public abstract class PanePageViewModelBase : ViewModelBase, IPanePageViewModel,
1313
{
1414
static readonly Uri paneUri = new Uri("github://pane");
1515
Subject<Uri> navigate = new Subject<Uri>();
16+
Exception error;
1617
bool isBusy;
1718
bool isLoading;
1819
string title;
@@ -29,6 +30,13 @@ protected PanePageViewModelBase()
2930
Dispose(false);
3031
}
3132

33+
/// <inheritdoc/>
34+
public Exception Error
35+
{
36+
get { return error; }
37+
protected set { this.RaiseAndSetIfChanged(ref error, value); }
38+
}
39+
3240
/// <inheritdoc/>
3341
public bool IsBusy
3442
{

src/GitHub.App/ViewModels/GitHubPane/PullRequestDetailViewModel.cs

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ public class PullRequestDetailViewModel : PanePageViewModelBase, IPullRequestDet
4141
IReadOnlyList<IPullRequestChangeNode> changedFilesTree;
4242
IPullRequestCheckoutState checkoutState;
4343
IPullRequestUpdateState updateState;
44-
string errorMessage;
4544
string operationError;
4645
bool isCheckedOut;
4746
bool isFromFork;
@@ -217,15 +216,6 @@ public IPullRequestUpdateState UpdateState
217216
private set { this.RaiseAndSetIfChanged(ref updateState, value); }
218217
}
219218

220-
/// <summary>
221-
/// Gets an error message to display if loading fails.
222-
/// </summary>
223-
public string ErrorMessage
224-
{
225-
get { return errorMessage; }
226-
private set { this.RaiseAndSetIfChanged(ref errorMessage, value); }
227-
}
228-
229219
/// <summary>
230220
/// Gets the error message to be displayed in the action area as a result of an error in a
231221
/// git operation.
@@ -335,7 +325,6 @@ public async Task InitializeAsync(
335325
/// <summary>
336326
/// Loads the view model from octokit models.
337327
/// </summary>
338-
/// <param name="remoteRepositoryOwner">The owner of the remote repository.</param>
339328
/// <param name="pullRequest">The pull request model.</param>
340329
public async Task Load(IPullRequestModel pullRequest)
341330
{
@@ -430,11 +419,6 @@ public async Task Load(IPullRequestModel pullRequest)
430419
pullRequestsService.RemoveUnusedRemotes(LocalRepository).Subscribe(_ => { });
431420
}
432421
}
433-
catch (Exception ex)
434-
{
435-
log.Error(ex, "Error loading PullRequestModel");
436-
ErrorMessage = ex.Message.Trim();
437-
}
438422
finally
439423
{
440424
IsBusy = false;
@@ -448,7 +432,9 @@ public override async Task Refresh()
448432
{
449433
try
450434
{
435+
Error = null;
451436
OperationError = null;
437+
IsBusy = true;
452438
var pullRequest = await modelService.GetPullRequest(RemoteRepositoryOwner, LocalRepository.Name, Number);
453439
await Load(pullRequest);
454440
}
@@ -461,7 +447,8 @@ public override async Task Refresh()
461447
LocalRepository.Name,
462448
Number,
463449
modelService.ApiClient.HostAddress.Title);
464-
ErrorMessage = ex.Message.Trim();
450+
Error = ex;
451+
IsBusy = false;
465452
}
466453
}
467454

src/GitHub.Exports.Reactive/ViewModels/GitHubPane/IPanePageViewModel.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ namespace GitHub.ViewModels.GitHubPane
99
/// </summary>
1010
public interface IPanePageViewModel : IViewModel
1111
{
12+
/// <summary>
13+
/// Gets an exception representing an error state to display.
14+
/// </summary>
15+
Exception Error { get; }
16+
1217
/// <summary>
1318
/// Gets a value indicating whether the page is busy.
1419
/// </summary>

src/GitHub.Exports/ViewModels/GitHubPane/IGitHubPaneViewModel.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,28 @@
44

55
namespace GitHub.ViewModels.GitHubPane
66
{
7+
/// <summary>
8+
/// Describes the ways that the display of <see cref="IGitHubPaneViewModel.Content"/> can
9+
/// be overridden.
10+
/// </summary>
11+
public enum ContentOverride
12+
{
13+
/// <summary>
14+
/// No override, display the content.
15+
/// </summary>
16+
None,
17+
18+
/// <summary>
19+
/// Display a spinner instead of the content.
20+
/// </summary>
21+
Spinner,
22+
23+
/// <summary>
24+
/// Display an error instead of the content.
25+
/// </summary>
26+
Error
27+
}
28+
729
/// <summary>
830
/// The view model for the GitHub Pane.
931
/// </summary>
@@ -19,6 +41,12 @@ public interface IGitHubPaneViewModel : IViewModel
1941
/// </summary>
2042
IViewModel Content { get; }
2143

44+
/// <summary>
45+
/// Gets a value describing whether to display the <see cref="Content"/> or to override
46+
/// it with another view.
47+
/// </summary>
48+
ContentOverride ContentOverride { get; }
49+
2250
/// <summary>
2351
/// Gets a value indicating whether search is available on the current page.
2452
/// </summary>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
using System.Globalization;
3+
using System.Windows;
4+
using System.Windows.Data;
5+
using System.Windows.Markup;
6+
7+
namespace GitHub.UI
8+
{
9+
public class EqualsToVisibilityConverter : MarkupExtension, IValueConverter
10+
{
11+
readonly string visibleValue;
12+
13+
public EqualsToVisibilityConverter(string visibleValue)
14+
{
15+
this.visibleValue = visibleValue;
16+
}
17+
18+
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
19+
{
20+
return value?.ToString() == visibleValue ? Visibility.Visible : Visibility.Collapsed;
21+
}
22+
23+
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
24+
{
25+
throw new NotImplementedException();
26+
}
27+
28+
public override object ProvideValue(IServiceProvider serviceProvider) => this;
29+
}
30+
}

src/GitHub.UI/GitHub.UI.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
<DependentUpon>Spinner.xaml</DependentUpon>
9090
</Compile>
9191
<Compile Include="Converters\AllCapsConverter.cs" />
92+
<Compile Include="Converters\EqualsToVisibilityConverter.cs" />
9293
<Compile Include="Converters\MultiBooleanToVisibilityConverter.cs" />
9394
<Compile Include="Converters\NullToVisibilityConverter.cs" />
9495
<Compile Include="Converters\BranchNameConverter.cs" />

src/GitHub.VisualStudio/Views/GitHubPane/GitHubPaneView.xaml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
Style="{StaticResource PaneHorizontalSeparator}" />
7070

7171
<Grid>
72-
<DockPanel Visibility="{Binding Content.Content.IsLoading, Converter={u:BooleanToInverseVisibilityConverter}, FallbackValue=Visible}">
72+
<DockPanel Visibility="{Binding ContentOverride, Converter={u:EqualsToVisibilityConverter None}}">
7373
<u:GitHubProgressBar DockPanel.Dock="Top"
7474
Foreground="{DynamicResource GitHubAccentBrush}"
7575
IsIndeterminate="True"
@@ -81,7 +81,16 @@
8181
Height="48"
8282
HorizontalAlignment="Center"
8383
VerticalAlignment="Center"
84-
Visibility="{Binding Content.Content.IsLoading, Converter={u:BooleanToVisibilityConverter}, FallbackValue=Collapsed}"/>
84+
Visibility="{Binding ContentOverride, Converter={u:EqualsToVisibilityConverter Spinner}, FallbackValue=Collapsed}"/>
85+
<Border Background="White"
86+
HorizontalAlignment="Stretch"
87+
VerticalAlignment="Stretch"
88+
Visibility="{Binding ContentOverride, Converter={u:EqualsToVisibilityConverter Error}, FallbackValue=Collapsed}">
89+
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
90+
<u:OcticonImage Icon="alert" Width="32" Height="32" Margin="8"/>
91+
<TextBlock Text="{Binding Content.Content.Error.Message}" TextAlignment="Center" TextWrapping="Wrap"/>
92+
</StackPanel>
93+
</Border>
8594
</Grid>
8695
</DockPanel>
8796
</local:GenericGitHubPaneView>

0 commit comments

Comments
 (0)