diff options
author | 2019-10-01 21:51:34 +0200 | |
---|---|---|
committer | 2019-10-01 21:51:34 +0200 | |
commit | f8fbaad43522b91374eaed5e3df6fe47bc94862f (patch) | |
tree | e39b6301c183fe5e87c81f4f340e701faed2d3aa /src/features/webControls/components | |
parent | feat(Service API): Share `team`, `url` and `hasCustomIcon` with service (diff) | |
download | ferdium-app-f8fbaad43522b91374eaed5e3df6fe47bc94862f.tar.gz ferdium-app-f8fbaad43522b91374eaed5e3df6fe47bc94862f.tar.zst ferdium-app-f8fbaad43522b91374eaed5e3df6fe47bc94862f.zip |
feat(Custom Websites): Add simple browser controls
Diffstat (limited to 'src/features/webControls/components')
-rw-r--r-- | src/features/webControls/components/WebControls.js | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/src/features/webControls/components/WebControls.js b/src/features/webControls/components/WebControls.js new file mode 100644 index 000000000..03f601a17 --- /dev/null +++ b/src/features/webControls/components/WebControls.js | |||
@@ -0,0 +1,190 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer } from 'mobx-react'; | ||
4 | import injectSheet from 'react-jss'; | ||
5 | import { Icon } from '@meetfranz/ui'; | ||
6 | |||
7 | import { | ||
8 | mdiReload, mdiArrowRight, mdiArrowLeft, mdiHomeOutline, | ||
9 | } from '@mdi/js'; | ||
10 | |||
11 | const styles = theme => ({ | ||
12 | root: { | ||
13 | background: theme.colorBackground, | ||
14 | position: 'relative', | ||
15 | borderLeft: [1, 'solid', theme.todos.todosLayer.borderLeftColor], | ||
16 | zIndex: 300, | ||
17 | height: 50, | ||
18 | display: 'flex', | ||
19 | flexDirection: 'row', | ||
20 | alignItems: 'center', | ||
21 | padding: [0, 20], | ||
22 | |||
23 | '& + div': { | ||
24 | height: 'calc(100% - 50px)', | ||
25 | }, | ||
26 | }, | ||
27 | button: { | ||
28 | width: 30, | ||
29 | height: 50, | ||
30 | transition: 'opacity 0.25s', | ||
31 | |||
32 | '&:hover': { | ||
33 | opacity: 0.8, | ||
34 | }, | ||
35 | |||
36 | '&:disabled': { | ||
37 | opacity: 0.5, | ||
38 | }, | ||
39 | }, | ||
40 | icon: { | ||
41 | width: '20px !important', | ||
42 | height: 20, | ||
43 | marginTop: 5, | ||
44 | }, | ||
45 | input: { | ||
46 | marginBottom: 0, | ||
47 | height: 'auto', | ||
48 | marginLeft: 10, | ||
49 | flex: 1, | ||
50 | border: 0, | ||
51 | padding: [4, 10], | ||
52 | borderRadius: theme.borderRadius, | ||
53 | background: theme.inputBackground, | ||
54 | color: theme.inputColor, | ||
55 | }, | ||
56 | inputButton: { | ||
57 | color: theme.colorText, | ||
58 | }, | ||
59 | }); | ||
60 | |||
61 | @injectSheet(styles) @observer | ||
62 | class WebControls extends Component { | ||
63 | static propTypes = { | ||
64 | classes: PropTypes.object.isRequired, | ||
65 | goHome: PropTypes.func.isRequired, | ||
66 | canGoBack: PropTypes.bool.isRequired, | ||
67 | goBack: PropTypes.func.isRequired, | ||
68 | canGoForward: PropTypes.bool.isRequired, | ||
69 | goForward: PropTypes.func.isRequired, | ||
70 | reload: PropTypes.func.isRequired, | ||
71 | url: PropTypes.string.isRequired, | ||
72 | navigate: PropTypes.func.isRequired, | ||
73 | } | ||
74 | |||
75 | static getDerivedStateFromProps(props, state) { | ||
76 | const { url } = props; | ||
77 | const { editUrl } = state; | ||
78 | |||
79 | if (!editUrl) { | ||
80 | return { | ||
81 | inputUrl: url, | ||
82 | editUrl: state.editUrl, | ||
83 | }; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | inputRef = React.createRef(); | ||
88 | |||
89 | state = { | ||
90 | inputUrl: '', | ||
91 | editUrl: false, | ||
92 | } | ||
93 | |||
94 | render() { | ||
95 | const { | ||
96 | classes, | ||
97 | goHome, | ||
98 | canGoBack, | ||
99 | goBack, | ||
100 | canGoForward, | ||
101 | goForward, | ||
102 | reload, | ||
103 | url, | ||
104 | navigate, | ||
105 | } = this.props; | ||
106 | |||
107 | const { | ||
108 | inputUrl, | ||
109 | editUrl, | ||
110 | } = this.state; | ||
111 | |||
112 | return ( | ||
113 | <div className={classes.root}> | ||
114 | <button | ||
115 | onClick={goHome} | ||
116 | type="button" | ||
117 | className={classes.button} | ||
118 | > | ||
119 | <Icon | ||
120 | icon={mdiHomeOutline} | ||
121 | className={classes.icon} | ||
122 | /> | ||
123 | </button> | ||
124 | <button | ||
125 | onClick={goBack} | ||
126 | type="button" | ||
127 | className={classes.button} | ||
128 | disabled={!canGoBack} | ||
129 | > | ||
130 | <Icon | ||
131 | icon={mdiArrowLeft} | ||
132 | className={classes.icon} | ||
133 | /> | ||
134 | </button> | ||
135 | <button | ||
136 | onClick={goForward} | ||
137 | type="button" | ||
138 | className={classes.button} | ||
139 | disabled={!canGoForward} | ||
140 | > | ||
141 | <Icon | ||
142 | icon={mdiArrowRight} | ||
143 | className={classes.icon} | ||
144 | /> | ||
145 | </button> | ||
146 | <button | ||
147 | onClick={reload} | ||
148 | type="button" | ||
149 | className={classes.button} | ||
150 | > | ||
151 | <Icon | ||
152 | icon={mdiReload} | ||
153 | className={classes.icon} | ||
154 | /> | ||
155 | </button> | ||
156 | <input | ||
157 | value={editUrl ? inputUrl : url} | ||
158 | className={classes.input} | ||
159 | onChange={event => this.setState({ | ||
160 | inputUrl: event.target.value, | ||
161 | })} | ||
162 | onFocus={(event) => { | ||
163 | event.target.select(); | ||
164 | this.setState({ | ||
165 | editUrl: true, | ||
166 | }); | ||
167 | }} | ||
168 | onKeyDown={(event) => { | ||
169 | if (event.key === 'Enter') { | ||
170 | this.setState({ | ||
171 | editUrl: false, | ||
172 | }); | ||
173 | navigate(inputUrl); | ||
174 | this.inputRef.current.blur(); | ||
175 | } else if (event.key === 'Escape') { | ||
176 | this.setState({ | ||
177 | editUrl: false, | ||
178 | inputUrl: url, | ||
179 | }); | ||
180 | event.target.blur(); | ||
181 | } | ||
182 | }} | ||
183 | ref={this.inputRef} | ||
184 | /> | ||
185 | </div> | ||
186 | ); | ||
187 | } | ||
188 | } | ||
189 | |||
190 | export default WebControls; | ||