Skip to content

Commit 7d31ad2

Browse files
author
Sheng Ran
committed
Favicon shows the status
1 parent 74bd331 commit 7d31ad2

File tree

7 files changed

+81
-9
lines changed

7 files changed

+81
-9
lines changed

src/main/webapp/js/components/App.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { State, Route, BoardView } from '../state';
55
import Graph from './Graph';
66
import BoardList from './BoardList';
77
import ErrorPage from './ErrorPage';
8+
import StatusFavicon from './StatusFavicon';
89

910
type Props = {
1011
isLoading: boolean,
@@ -26,14 +27,17 @@ class App extends Component {
2627
return <ErrorPage message={error}/>;
2728
if (route.path === 'BOARDS') return <BoardList />;
2829
if (route.path === 'BOARD') {
29-
if (board)
30+
if (board) {
31+
document.title = board.title;
3032
return (
3133
<div>
34+
<StatusFavicon status={board.status}/>
3235
<Graph
3336
board={board}
3437
/>
3538
</div>
3639
);
40+
}
3741
else
3842
return (
3943
<h1 style={{ color: '#BABABA' }} className="info">
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// @flow
2+
import { PureComponent } from 'react';
3+
import type { Status } from '../state';
4+
import { statusToColor } from '../utils';
5+
6+
type Props = {
7+
status: Status
8+
};
9+
10+
const Radius = 32;
11+
12+
class StatusFavicon extends PureComponent {
13+
props: Props;
14+
15+
canvas = null;
16+
17+
render() {
18+
return null;
19+
}
20+
21+
componentDidUpdate() {
22+
this.update();
23+
}
24+
25+
componentDidMount() {
26+
this.update();
27+
}
28+
29+
componentWillUnmount() {
30+
const favicon = document.querySelector('#favicon');
31+
if (favicon instanceof HTMLLinkElement) {
32+
favicon.href = '';
33+
}
34+
}
35+
36+
update() {
37+
let { canvas, props: { status } } = this;
38+
if (canvas === null) {
39+
this.canvas = canvas = document.createElement('canvas');
40+
canvas.width = 2 * Radius;
41+
canvas.height = 2 * Radius;
42+
}
43+
const ctx = canvas.getContext('2d');
44+
if (ctx) {
45+
ctx.beginPath();
46+
ctx.arc(Radius, Radius, Radius / 2, 0, 2 * Math.PI);
47+
ctx.fillStyle = statusToColor(status);
48+
ctx.fill();
49+
}
50+
const favicon = document.querySelector('#favicon');
51+
if (favicon instanceof HTMLLinkElement) {
52+
favicon.href = canvas.toDataURL('image/x-icon');
53+
}
54+
}
55+
}
56+
57+
export default StatusFavicon;

src/main/webapp/js/state.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export type Route = {
6464

6565
export type Link = [string, string];
6666

67-
type Status = 'Unknown' | 'Success' | 'Error' | 'Warning';
67+
export type Status = 'Unknown' | 'Success' | 'Error' | 'Warning';
6868

6969
export type State = {
7070
currentBoard: ?string,

src/main/webapp/js/utils/fetcher.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const resolve = res => {
55
return res.text();
66
};
77

8-
const fetcher = (url, options) =>
8+
export const fetcher = (url, options) =>
99
fetch(url, options)
1010
.then(
1111
res => Promise.all([resolve(res), Promise.resolve(res)]),
@@ -21,6 +21,4 @@ fetch(url, options)
2121
return Promise.resolve(response);
2222
else
2323
return Promise.reject(response);
24-
});
25-
26-
export { fetcher };
24+
});

src/main/webapp/js/utils/index.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,14 @@
1-
export * from './fetcher';
2-
export * from './api';
1+
// @flow
2+
import type { Status } from '../state';
3+
4+
export { fetcher } from './fetcher';
5+
export * from './api';
6+
7+
export const statusToColor = (status: Status): string => {
8+
switch(status) {
9+
case 'SUCCESS': return '#2ebd59';
10+
case 'WARNING': return '#fdb843';
11+
case 'ERROR': return '#e7624f';
12+
default: return '#e0e0e0';
13+
}
14+
};

src/main/webapp/public/index.ejs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<meta charset="utf-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1">
66
<title><%= htmlWebpackPlugin.options.title %></title>
7+
<link id="favicon" href="" rel="icon" type="image/x-icon" />
78
<% for(var i = 0; i < htmlWebpackPlugin.files.css.length; ++i) { %>
89
<link rel="stylesheet" type="text/css" href="<%=htmlWebpackPlugin.files.css[i] %>"></script>
910
<% } %>

webpack.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ var config = {
5656
filename: 'index.html',
5757
template: path.resolve(baseDir, 'public/index.ejs'),
5858
inject: false,
59-
title: 'Slab'
59+
title: 'SLAB'
6060
}),
6161
new CopyWebpackPlugin(
6262
[

0 commit comments

Comments
 (0)