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

Commit 6d89938

Browse files
authored
Merge pull request #370 from github/shana/stop-ui-controller-properly
Stop the UIController properly in the GitHubPane
2 parents 3e560f3 + 2464be7 commit 6d89938

File tree

1 file changed

+82
-24
lines changed

1 file changed

+82
-24
lines changed

src/GitHub.VisualStudio/UI/Views/GitHubPaneViewModel.cs

Lines changed: 82 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace GitHub.VisualStudio.UI.Views
2626
[PartCreationPolicy(CreationPolicy.NonShared)]
2727
public class GitHubPaneViewModel : TeamExplorerItemBase, IGitHubPaneViewModel
2828
{
29+
const UIControllerFlow DefaultControllerFlow = UIControllerFlow.PullRequests;
30+
2931
bool initialized;
3032
readonly CompositeDisposable disposables = new CompositeDisposable();
3133
IUIController uiController;
@@ -40,6 +42,7 @@ public class GitHubPaneViewModel : TeamExplorerItemBase, IGitHubPaneViewModel
4042
bool navigatingViaArrows;
4143
bool disabled;
4244
Microsoft.VisualStudio.Shell.OleMenuCommand back, forward, refresh;
45+
int latestReloadCallId;
4346

4447
[ImportingConstructor]
4548
public GitHubPaneViewModel(ISimpleApiClientFactory apiFactory, ITeamExplorerServiceHolder holder,
@@ -51,8 +54,6 @@ public GitHubPaneViewModel(ISimpleApiClientFactory apiFactory, ITeamExplorerServ
5154
syncContext = SynchronizationContext.Current;
5255
CancelCommand = ReactiveCommand.Create();
5356
Title = "GitHub";
54-
55-
hosts.WhenAnyValue(x => x.IsLoggedInToAnyHost).Subscribe(_ => Reload().Forget());
5657
}
5758

5859
public override void Initialize(IServiceProvider serviceProvider)
@@ -87,6 +88,8 @@ public override void Initialize(IServiceProvider serviceProvider)
8788
initialized = true;
8889

8990
base.Initialize(serviceProvider);
91+
92+
hosts.WhenAnyValue(x => x.IsLoggedInToAnyHost).Subscribe(_ => Reload().Forget());
9093
}
9194

9295
public void Initialize([AllowNull] ViewWithData data)
@@ -105,53 +108,103 @@ protected override void RepoChanged(bool changed)
105108
if (!changed)
106109
return;
107110

111+
Stop();
108112
IsGitHubRepo = null;
109113
Reload().Forget();
110114
}
111115

116+
/// <summary>
117+
/// This method is reentrant, so all await calls need to be done before
118+
/// any actions are performed on the data. More recent calls to this method
119+
/// will cause previous calls pending on await calls to exit early.
120+
/// </summary>
121+
/// <returns></returns>
112122
async Task Reload([AllowNull] ViewWithData data = null, bool navigating = false)
113123
{
124+
if (!initialized)
125+
return;
126+
127+
latestReloadCallId++;
128+
var reloadCallId = latestReloadCallId;
129+
114130
navigatingViaArrows = navigating;
115131

116132
if (!IsGitHubRepo.HasValue)
117-
IsGitHubRepo = await IsAGitHubRepo();
118-
119-
if (!IsGitHubRepo.Value)
120133
{
121-
if (uiController != null)
122-
{
123-
Stop();
124-
//var factory = ServiceProvider.GetExportedValue<IUIFactory>();
125-
//var c = factory.CreateViewAndViewModel(UIViewType.LoggedOut);
126-
//Control = c.View;
127-
}
128-
return;
134+
var isGitHubRepo = await IsAGitHubRepo();
135+
if (reloadCallId != latestReloadCallId)
136+
return;
137+
138+
IsGitHubRepo = isGitHubRepo;
129139
}
130140

131141
var connection = await connectionManager.LookupConnection(ActiveRepo);
132-
IsLoggedIn = await connection.IsLoggedIn(hosts);
142+
if (reloadCallId != latestReloadCallId)
143+
return;
133144

134-
if (IsLoggedIn)
145+
if (connection == null)
146+
IsLoggedIn = false;
147+
else
135148
{
136-
if (uiController == null || (data != null && data.ActiveFlow != uiController.SelectedFlow))
137-
StartFlow(data?.ActiveFlow ?? UIControllerFlow.PullRequests, connection, data);
138-
else if (data != null || currentNavItem >= 0)
139-
uiController.Jump(data ?? navStack[currentNavItem]);
149+
var isLoggedIn = await connection.IsLoggedIn(hosts);
150+
if (reloadCallId != latestReloadCallId)
151+
return;
152+
153+
IsLoggedIn = isLoggedIn;
140154
}
155+
156+
if (!IsGitHubRepo.Value)
157+
{
158+
//LoadView(UIViewType.NotAGitHubRepo);
159+
}
160+
161+
else if (!IsLoggedIn)
162+
{
163+
LoadView(UIViewType.LoggedOut);
164+
}
165+
141166
else
167+
{
168+
LoadView(data?.ActiveFlow ?? DefaultControllerFlow, connection, data);
169+
}
170+
}
171+
172+
void LoadView(UIControllerFlow flow, IConnection connection = null, ViewWithData data = null, UIViewType type = UIViewType.None)
173+
{
174+
// if we're loading a single view or a different flow, we need to stop the current controller
175+
var restart = flow == UIControllerFlow.None || uiController?.SelectedFlow != flow;
176+
177+
if (restart)
178+
Stop();
179+
180+
// if there's no selected flow, then just load a view directly
181+
if (flow == UIControllerFlow.None)
142182
{
143183
var factory = ServiceProvider.GetExportedValue<IUIFactory>();
144-
var c = factory.CreateViewAndViewModel(UIViewType.LoggedOut);
184+
var c = factory.CreateViewAndViewModel(type);
145185
c.View.DataContext = c.ViewModel;
146186
Control = c.View;
147187
}
148-
return;
188+
// it's a new flow!
189+
else if (restart)
190+
{
191+
StartFlow(flow, connection, data);
192+
}
193+
// navigate to a requested view within the currently running uiController
194+
else
195+
{
196+
uiController.Jump(data ?? navStack[currentNavItem]);
197+
}
198+
}
199+
200+
void LoadView(UIViewType type)
201+
{
202+
LoadView(UIControllerFlow.None, type: type);
149203
}
150204

151205
void StartFlow(UIControllerFlow controllerFlow, [AllowNull]IConnection conn, ViewWithData data = null)
152206
{
153-
if (uiController != null)
154-
Stop();
207+
Stop();
155208

156209
if (conn == null)
157210
return;
@@ -249,12 +302,17 @@ void DisableButtons()
249302

250303
void Stop()
251304
{
305+
if (uiController == null)
306+
return;
307+
308+
DisableButtons();
252309
windowController?.Close();
253310
uiController.Stop();
254311
disposables.Clear();
255312
uiController = null;
256313
currentNavItem = -1;
257314
navStack.Clear();
315+
UpdateToolbar();
258316
}
259317

260318
string title;
@@ -307,4 +365,4 @@ protected override void Dispose(bool disposing)
307365
base.Dispose(disposing);
308366
}
309367
}
310-
}
368+
}

0 commit comments

Comments
 (0)