Skip to content

Commit ad5ea64

Browse files
committed
Refactor plugin activation function to be async
1 parent 3928a06 commit ad5ea64

File tree

2 files changed

+82
-95
lines changed

2 files changed

+82
-95
lines changed

src/index.ts

Lines changed: 44 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -58,73 +58,72 @@ export default plugin;
5858
/**
5959
* Activate the running plugin.
6060
*/
61-
function activate(
61+
async function activate(
6262
app: JupyterFrontEnd,
6363
mainMenu: IMainMenu,
6464
restorer: ILayoutRestorer,
6565
factory: IFileBrowserFactory,
6666
renderMime: IRenderMimeRegistry,
6767
settingRegistry: ISettingRegistry
68-
): IGitExtension {
69-
const key = plugin.id;
68+
): Promise<IGitExtension> {
69+
let settings: ISettingRegistry.ISettings;
7070

71+
// Register Git icons with the icon registry
7172
registerGitIcons(defaultIconRegistry);
7273

74+
// Get a reference to the default file browser extension
75+
const filebrowser = factory.defaultBrowser;
76+
77+
// Wait for the application and file browser extension to be restored:
78+
await Promise.all([app.restored, filebrowser.model.restored]);
79+
80+
// Attempt to load application settings
81+
try {
82+
settings = await settingRegistry.load(plugin.id);
83+
} catch (error) {
84+
console.error(`Failed to load settings for the Git Exetnsion.\n${error}`);
85+
}
7386
// Create the Git model
74-
let gitExtension = new GitExtension(app);
87+
const gitExtension = new GitExtension(app, settings);
7588

76-
// Connect file browser with git model
77-
const filebrowser = factory.defaultBrowser;
89+
// Sync the Git extension path with the file browser extension's current path
90+
gitExtension.pathRepository = filebrowser.model.path;
7891

7992
// Whenever the file browser path changes, sync the Git extension path
8093
filebrowser.model.pathChanged.connect(
8194
(model: FileBrowserModel, change: IChangedArgs<string>) => {
8295
gitExtension.pathRepository = change.newValue;
8396
}
8497
);
85-
8698
// Whenever a user adds/renames/saves/deletes/modifies a file within the lab environment, refresh the Git status
8799
filebrowser.model.fileChanged.connect(() => gitExtension.refreshStatus());
88100

89-
// Whenever we restore the application, sync the Git extension path
90-
Promise.all([app.restored, filebrowser.model.restored]).then(() => {
91-
gitExtension.pathRepository = filebrowser.model.path;
92-
});
93-
94-
/* Create the widgets */
95-
settingRegistry
96-
.load(key)
97-
.then(settings => {
98-
// Create the Git widget sidebar
99-
const gitPlugin = new GitWidget(gitExtension, settings, renderMime);
100-
gitPlugin.id = 'jp-git-sessions';
101-
gitPlugin.title.iconClass = `jp-SideBar-tabIcon jp-GitIcon`;
102-
gitPlugin.title.caption = 'Git';
103-
104-
// Let the application restorer track the running panel for restoration of
105-
// application state (e.g. setting the running panel as the current side bar
106-
// widget).
107-
restorer.add(gitPlugin, 'git-sessions');
108-
// Rank has been chosen somewhat arbitrarily to give priority to the running
109-
// sessions widget in the sidebar.
110-
app.shell.add(gitPlugin, 'left', { rank: 200 });
111-
112-
// add a menu for the plugin
113-
mainMenu.addMenu(
114-
createGitMenu(app, gitExtension, factory.defaultBrowser, settings),
115-
{ rank: 60 }
116-
);
117-
118-
// Pass along the plugin settings to the Git model:
119-
gitExtension.settings = settings;
120-
})
121-
.catch(reason => {
122-
console.error(
123-
`Failed to load settings for the Git Exetnsion.\n${reason}`
124-
);
125-
});
126-
101+
// Provided we were able to load application settings, create the extension widgets
102+
if (typeof settings !== void 0) {
103+
// Create the Git widget sidebar
104+
const gitPlugin = new GitWidget(gitExtension, settings, renderMime);
105+
gitPlugin.id = 'jp-git-sessions';
106+
gitPlugin.title.iconClass = 'jp-SideBar-tabIcon jp-GitIcon';
107+
gitPlugin.title.caption = 'Git';
108+
109+
// Let the application restorer track the running panel for restoration of
110+
// application state (e.g. setting the running panel as the current side bar
111+
// widget).
112+
restorer.add(gitPlugin, 'git-sessions');
113+
114+
// Rank has been chosen somewhat arbitrarily to give priority to the running
115+
// sessions widget in the sidebar.
116+
app.shell.add(gitPlugin, 'left', { rank: 200 });
117+
118+
// Add a menu for the plugin
119+
mainMenu.addMenu(
120+
createGitMenu(app, gitExtension, factory.defaultBrowser, settings),
121+
{ rank: 60 }
122+
);
123+
}
124+
// Add a clone button to the file browser extension toolbar
127125
addCloneButton(gitExtension, factory.defaultBrowser);
126+
128127
return gitExtension;
129128
}
130129

src/model.ts

Lines changed: 38 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,16 @@ import { ISignal, Signal } from '@phosphor/signaling';
1313
import { httpGitRequest } from './git';
1414
import { IGitExtension, Git } from './tokens';
1515

16+
// Default refresh interval (in milliseconds) for polling the current Git status:
17+
const DEFAULT_REFRESH_INTERVAL = 3000; // ms
18+
1619
/** Main extension class */
1720
export class GitExtension implements IGitExtension, IDisposable {
18-
constructor(app: JupyterFrontEnd = null) {
21+
constructor(
22+
app: JupyterFrontEnd = null,
23+
settings?: ISettingRegistry.ISettings
24+
) {
25+
const model = this;
1926
this._app = app;
2027

2128
// Load the server root path
@@ -26,35 +33,39 @@ export class GitExtension implements IGitExtension, IDisposable {
2633
.catch(reason => {
2734
console.error(`Fail to get the server root path.\n${reason}`);
2835
});
29-
}
3036

31-
/**
32-
* Plugin settings.
33-
*/
34-
set settings(settings: ISettingRegistry.ISettings) {
35-
if (this._settings) {
36-
this._settings.changed.disconnect(this._onSettingsChange, this);
37-
}
38-
settings.changed.connect(this._onSettingsChange, this);
39-
if (this._poll) {
40-
const freq = this._poll.frequency;
41-
this._poll.frequency = {
37+
let interval: number;
38+
if (settings) {
39+
interval = settings.composite.refreshInterval as number;
40+
settings.changed.connect(onSettingsChange, this);
41+
} else {
42+
interval = DEFAULT_REFRESH_INTERVAL;
43+
}
44+
const poll = new Poll({
45+
factory: () => model._refreshStatus(),
46+
frequency: {
47+
interval: interval,
48+
backoff: true,
49+
max: 300 * 1000
50+
},
51+
standby: 'when-hidden'
52+
});
53+
this._poll = poll;
54+
55+
/**
56+
* Callback invoked upon a change to plugin settings.
57+
*
58+
* @private
59+
* @param settings - settings registry
60+
*/
61+
function onSettingsChange(settings: ISettingRegistry.ISettings) {
62+
const freq = poll.frequency;
63+
poll.frequency = {
4264
interval: settings.composite.refreshInterval as number,
4365
backoff: freq.backoff,
4466
max: freq.max
4567
};
46-
} else {
47-
this._poll = new Poll({
48-
factory: () => this._refreshStatus(),
49-
frequency: {
50-
interval: settings.composite.refreshInterval as number,
51-
backoff: true,
52-
max: 300 * 1000
53-
},
54-
standby: 'when-hidden'
55-
});
5668
}
57-
this._settings = settings;
5869
}
5970

6071
/**
@@ -169,9 +180,7 @@ export class GitExtension implements IGitExtension, IDisposable {
169180
return;
170181
}
171182
this._isDisposed = true;
172-
if (this._poll) {
173-
this._poll.dispose();
174-
}
183+
this._poll.dispose();
175184
Signal.clearData(this);
176185
}
177186

@@ -349,13 +358,8 @@ export class GitExtension implements IGitExtension, IDisposable {
349358
}
350359

351360
async refreshStatus(): Promise<void> {
352-
if (this._poll) {
353-
await this._poll.refresh();
354-
await this._poll.tick;
355-
} else {
356-
await this._refreshStatus();
357-
await Promise.resolve();
358-
}
361+
await this._poll.refresh();
362+
await this._poll.tick;
359363
}
360364

361365
/** Refresh the git repository status */
@@ -924,21 +928,6 @@ export class GitExtension implements IGitExtension, IDisposable {
924928
return this._currentMarker;
925929
}
926930

927-
/**
928-
* Callback invoked upon a change to plugin settings.
929-
*
930-
* @private
931-
* @param settings - settings registry
932-
*/
933-
private _onSettingsChange(settings: ISettingRegistry.ISettings) {
934-
const freq = this._poll.frequency;
935-
this._poll.frequency = {
936-
interval: settings.composite.refreshInterval as number,
937-
backoff: freq.backoff,
938-
max: freq.max
939-
};
940-
}
941-
942931
private _status: Git.IStatusFileResult[] = [];
943932
private _pathRepository: string | null = null;
944933
private _branches: Git.IBranch[];
@@ -952,7 +941,6 @@ export class GitExtension implements IGitExtension, IDisposable {
952941
private _readyPromise: Promise<void> = Promise.resolve();
953942
private _pendingReadyPromise = 0;
954943
private _poll: Poll;
955-
private _settings: ISettingRegistry.ISettings | null = null;
956944
private _headChanged = new Signal<IGitExtension, void>(this);
957945
private _markChanged = new Signal<IGitExtension, void>(this);
958946
private _repositoryChanged = new Signal<

0 commit comments

Comments
 (0)