1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94 | 1x
1x
1x
1x
1x
1x
1x
1x
1x
1x
1x
1x
1x
| import {List} from "immutable";
import * as React from "react";
import {branch, compose, lifecycle, renderNothing, withHandlers, withState} from "recompose";
import {Theme} from "./types/Theme";
export interface ThemeProps {
channel: any;
api: any;
active: boolean;
}
interface ThemeState {
theme: Theme;
setTheme: (theme: Theme) => void;
themes: List<Theme>;
setThemes: (themes: List<Theme>) => void;
}
interface ThemeHandler {
onSelectTheme: (theme: Theme) => void;
onReceiveThemes: (theme: Theme[]) => void;
}
type BaseComponentProps = ThemeProps & ThemeState & ThemeHandler;
const BaseComponent: React.SFC<BaseComponentProps> = ({onSelectTheme, themes, theme}) => (
<div style={RowStyle}>
{themes.map((th, i) => {
const buttonStyle = th === theme ? SelectedButtonStyle : ButtonStyle;
return <div style={buttonStyle} key={i} onClick={() => onSelectTheme(th)}>{th.name}</div>;
}).toArray()}
</div>
);
export const Themes = compose<BaseComponentProps, ThemeProps>(
withState("theme", "setTheme", null),
withState("themes", "setThemes", List()),
withHandlers<ThemeProps & ThemeState, ThemeHandler>({
onSelectTheme: ({channel, setTheme, api}) => (theme) => {
setTheme(theme);
api.setQueryParams({theme: theme.name});
channel.emit("selectTheme", theme);
},
onReceiveThemes: ({setTheme, setThemes, channel, api}) => (newThemes: Theme[]) => {
const themes = List(newThemes);
const themeName = api.getQueryParam("theme");
setThemes(List(themes));
if (themes.count() > 0) {
const theme = themes.find((t) => t.name === themeName) || themes.first();
setTheme(theme);
channel.emit("selectTheme", theme);
}
},
}),
lifecycle<BaseComponentProps, BaseComponentProps>({
componentDidMount() {
const {channel, onReceiveThemes} = this.props;
channel.on("setThemes", onReceiveThemes);
},
componentWillUnmount() {
const {channel, onReceiveThemes} = this.props;
channel.removeListener("setThemes", onReceiveThemes);
},
}),
branch<BaseComponentProps>(
({theme, active}) => !theme || !active,
renderNothing,
),
)(BaseComponent);
const RowStyle: React.CSSProperties = {
margin: "10px",
display: "flex",
};
const ButtonStyle: React.CSSProperties = {
border: "1px solid #BBB",
borderRadius: "6px",
color: "#BBB",
padding: "13px",
marginRight: "15px",
cursor: "pointer",
// tslint:disable-next-line:max-line-length
fontFamily: "-apple-system, \".SFNSText-Regular\", \"San Francisco\", BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", \"Lucida Grande\", \"Arial\", sans-serif",
lineHeight: "25px",
};
const SelectedButtonStyle: React.CSSProperties = {
...ButtonStyle,
backgroundColor: "#BBB",
color: "#333",
fontWeight: "bold",
};
|