Skip to content

Commit fa7eaa5

Browse files
authored
Merge pull request #893 from fcollonval/fcollonval/issue803
Use animated icon as status indicator
2 parents abcdc1e + 36ca710 commit fa7eaa5

File tree

4 files changed

+55
-25
lines changed

4 files changed

+55
-25
lines changed

src/widgets/StatusWidget.ts renamed to src/components/StatusWidget.tsx

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
1+
import { ReactWidget } from '@jupyterlab/apputils';
12
import { ISettingRegistry } from '@jupyterlab/settingregistry';
23
import { IStatusBar } from '@jupyterlab/statusbar';
3-
import { Widget } from '@lumino/widgets';
44
import { TranslationBundle } from '@jupyterlab/translation';
5-
import { statusWidgetClass } from '../style/StatusWidget';
5+
import React from 'react';
6+
import { gitIcon } from '../style/icons';
7+
import {
8+
statusAnimatedIconClass,
9+
statusIconClass
10+
} from '../style/StatusWidget';
611
import { IGitExtension } from '../tokens';
712
import { sleep } from '../utils';
813

9-
/**
10-
* Class for creating a status bar widget.
11-
*/
12-
export class StatusWidget extends Widget {
14+
export class StatusWidget extends ReactWidget {
1315
/**
1416
* Returns a status bar widget.
1517
* @param trans - The language translator
1618
* @returns widget
1719
*/
1820
constructor(trans: TranslationBundle) {
1921
super();
20-
this.addClass(statusWidgetClass);
2122
this._trans = trans;
2223
}
2324

@@ -27,16 +28,23 @@ export class StatusWidget extends Widget {
2728
set status(text: string) {
2829
this._status = text;
2930
if (!this._locked) {
30-
this._lock();
31-
this.refresh();
31+
this._animate();
3232
}
3333
}
3434

35-
/**
36-
* Refreshes the status widget.
37-
*/
38-
refresh(): void {
39-
this.node.textContent = 'Git: ' + this._trans.__(this._status);
35+
render(): JSX.Element {
36+
return (
37+
<div title={`Git: ${this._trans.__(this._status)}`}>
38+
<gitIcon.react
39+
className={
40+
this._status !== 'idle' ? statusAnimatedIconClass : statusIconClass
41+
}
42+
left={'1px'}
43+
top={'3px'}
44+
stylesheet={'statusBar'}
45+
/>
46+
</div>
47+
);
4048
}
4149

4250
/**
@@ -46,11 +54,12 @@ export class StatusWidget extends Widget {
4654
*
4755
* - This is used to throttle updates in order to prevent "flashing" messages.
4856
*/
49-
async _lock(): Promise<void> {
57+
async _animate(): Promise<void> {
5058
this._locked = true;
59+
this.update();
5160
await sleep(500);
5261
this._locked = false;
53-
this.refresh();
62+
this.update();
5463
}
5564

5665
/**

src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@ import { IMainMenu } from '@jupyterlab/mainmenu';
1111
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
1212
import { ISettingRegistry } from '@jupyterlab/settingregistry';
1313
import { IStatusBar } from '@jupyterlab/statusbar';
14+
import { ITranslator, nullTranslator } from '@jupyterlab/translation';
1415
import {
1516
addCommands,
1617
addFileBrowserContextMenu,
1718
createGitMenu
1819
} from './commandsAndMenu';
20+
import { addStatusBarWidget } from './components/StatusWidget';
1921
import { GitExtension } from './model';
2022
import { getServerSettings } from './server';
2123
import { gitIcon } from './style/icons';
2224
import { Git, IGitExtension } from './tokens';
2325
import { addCloneButton } from './widgets/gitClone';
2426
import { GitWidget } from './widgets/GitWidget';
25-
import { addStatusBarWidget } from './widgets/StatusWidget';
26-
import { ITranslator, nullTranslator } from '@jupyterlab/translation';
2727

2828
export { Git, IGitExtension } from './tokens';
2929

src/style/StatusWidget.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,30 @@
1-
import { style } from 'typestyle';
1+
import { keyframes, style } from 'typestyle';
22

3-
export const statusWidgetClass = style({
4-
color: 'var(--jp-ui-font-color1)',
5-
fontFamily: 'var(--jp-ui-font-family)',
6-
fontSize: 'var(--jp-ui-font-size1)',
7-
lineHeight: '24px'
3+
const fillAnimation = keyframes({
4+
to: { fillOpacity: 1 }
5+
});
6+
7+
export const statusIconClass = style({
8+
$nest: {
9+
'& .jp-icon3': {
10+
animationName: fillAnimation,
11+
animationDuration: '1s'
12+
}
13+
}
14+
});
15+
16+
const pathAnimation = keyframes({
17+
'0%': { fillOpacity: 1 },
18+
'50%': { fillOpacity: 0.6 },
19+
'100%': { fillOpacity: 1 }
20+
});
21+
22+
export const statusAnimatedIconClass = style({
23+
$nest: {
24+
'& .jp-icon3': {
25+
animationName: pathAnimation,
26+
animationDuration: '2s',
27+
animationIterationCount: 'infinite'
28+
}
29+
}
830
});

style/icons/git.svg

Lines changed: 0 additions & 1 deletion
Loading

0 commit comments

Comments
 (0)