Skip to content

Commit b83568a

Browse files
authored
Merge pull request #459 from kgryte/refresh-interval
Update refresh interval
2 parents 0367382 + 170b15a commit b83568a

File tree

3 files changed

+94
-52
lines changed

3 files changed

+94
-52
lines changed

schema/plugin.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
"title": "Simple staging flag",
1717
"description": "If true, use a simplified concept of staging. Only files with changes are shown (instead of showing staged/changed/untracked), and all files with changes will be automatically staged",
1818
"default": false
19+
},
20+
"refreshInterval": {
21+
"type": "integer",
22+
"title": "Refresh interval",
23+
"description": "Number of milliseconds between polling the file system for changes.",
24+
"default": 3000
1925
}
2026
}
2127
}

src/index.ts

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -58,62 +58,71 @@ 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

73-
// Create the Git model
74-
let gitExtension = new GitExtension(app);
75-
// Connect file browser with git model
74+
// Get a reference to the default file browser extension
7675
const filebrowser = factory.defaultBrowser;
76+
77+
// Attempt to load application settings
78+
try {
79+
settings = await settingRegistry.load(plugin.id);
80+
} catch (error) {
81+
console.error(`Failed to load settings for the Git Extension.\n${error}`);
82+
}
83+
// Create the Git model
84+
const gitExtension = new GitExtension(app, settings);
85+
86+
// Whenever we restore the application, sync the Git extension path
87+
Promise.all([app.restored, filebrowser.model.restored]).then(() => {
88+
gitExtension.pathRepository = filebrowser.model.path;
89+
});
90+
91+
// Whenever the file browser path changes, sync the Git extension path
7792
filebrowser.model.pathChanged.connect(
7893
(model: FileBrowserModel, change: IChangedArgs<string>) => {
7994
gitExtension.pathRepository = change.newValue;
8095
}
8196
);
82-
Promise.all([app.restored, filebrowser.model.restored]).then(() => {
83-
gitExtension.pathRepository = filebrowser.model.path;
84-
});
85-
86-
/* Create the widgets */
87-
settingRegistry
88-
.load(key)
89-
.then(settings => {
90-
// Create the Git widget sidebar
91-
const gitPlugin = new GitWidget(gitExtension, settings, renderMime);
92-
gitPlugin.id = 'jp-git-sessions';
93-
gitPlugin.title.iconClass = `jp-SideBar-tabIcon jp-GitIcon`;
94-
gitPlugin.title.caption = 'Git';
95-
96-
// Let the application restorer track the running panel for restoration of
97-
// application state (e.g. setting the running panel as the current side bar
98-
// widget).
99-
restorer.add(gitPlugin, 'git-sessions');
100-
// Rank has been chosen somewhat arbitrarily to give priority to the running
101-
// sessions widget in the sidebar.
102-
app.shell.add(gitPlugin, 'left', { rank: 200 });
103-
104-
// add a menu for the plugin
105-
mainMenu.addMenu(
106-
createGitMenu(app, gitExtension, factory.defaultBrowser, settings),
107-
{ rank: 60 }
108-
);
109-
})
110-
.catch(reason => {
111-
console.error(
112-
`Failed to load settings for the Git Exetnsion.\n${reason}`
113-
);
114-
});
115-
97+
// Whenever a user adds/renames/saves/deletes/modifies a file within the lab environment, refresh the Git status
98+
filebrowser.model.fileChanged.connect(() => gitExtension.refreshStatus());
99+
100+
// Provided we were able to load application settings, create the extension widgets
101+
if (settings) {
102+
// Create the Git widget sidebar
103+
const gitPlugin = new GitWidget(gitExtension, settings, renderMime);
104+
gitPlugin.id = 'jp-git-sessions';
105+
gitPlugin.title.iconClass = 'jp-SideBar-tabIcon jp-GitIcon';
106+
gitPlugin.title.caption = 'Git';
107+
108+
// Let the application restorer track the running panel for restoration of
109+
// application state (e.g. setting the running panel as the current side bar
110+
// widget).
111+
restorer.add(gitPlugin, 'git-sessions');
112+
113+
// Rank has been chosen somewhat arbitrarily to give priority to the running
114+
// sessions widget in the sidebar.
115+
app.shell.add(gitPlugin, 'left', { rank: 200 });
116+
117+
// Add a menu for the plugin
118+
mainMenu.addMenu(
119+
createGitMenu(app, gitExtension, factory.defaultBrowser, settings),
120+
{ rank: 60 }
121+
);
122+
}
123+
// Add a clone button to the file browser extension toolbar
116124
addCloneButton(gitExtension, factory.defaultBrowser);
125+
117126
return gitExtension;
118127
}
119128

src/model.ts

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { JupyterFrontEnd } from '@jupyterlab/application';
2-
import { IChangedArgs, PathExt, Poll } from '@jupyterlab/coreutils';
2+
import {
3+
IChangedArgs,
4+
PathExt,
5+
Poll,
6+
ISettingRegistry
7+
} from '@jupyterlab/coreutils';
38
import { ServerConnection } from '@jupyterlab/services';
49
import { CommandRegistry } from '@phosphor/commands';
510
import { JSONObject } from '@phosphor/coreutils';
@@ -8,14 +13,16 @@ import { ISignal, Signal } from '@phosphor/signaling';
813
import { httpGitRequest } from './git';
914
import { IGitExtension, Git } from './tokens';
1015

11-
/**
12-
* The default duration of the auto-refresh in ms
13-
*/
14-
const DEFAULT_REFRESH_INTERVAL = 10000;
16+
// Default refresh interval (in milliseconds) for polling the current Git status (NOTE: this value should be the same value as in the plugin settings schema):
17+
const DEFAULT_REFRESH_INTERVAL = 3000; // ms
1518

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
@@ -27,18 +34,38 @@ export class GitExtension implements IGitExtension, IDisposable {
2734
console.error(`Fail to get the server root path.\n${reason}`);
2835
});
2936

30-
const refreshInterval = DEFAULT_REFRESH_INTERVAL;
31-
32-
// Start watching the repository
33-
this._poll = new Poll({
34-
factory: () => this._refreshStatus(),
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(),
3546
frequency: {
36-
interval: refreshInterval,
47+
interval: interval,
3748
backoff: true,
3849
max: 300 * 1000
3950
},
4051
standby: 'when-hidden'
4152
});
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 = {
64+
interval: settings.composite.refreshInterval as number,
65+
backoff: freq.backoff,
66+
max: freq.max
67+
};
68+
}
4269
}
4370

4471
/**

0 commit comments

Comments
 (0)