aboutsummaryrefslogtreecommitdiffstats
path: root/src/features/webControls/components/WebControls.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/features/webControls/components/WebControls.js')
-rw-r--r--src/features/webControls/components/WebControls.js239
1 files changed, 239 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..a39fcfe0e
--- /dev/null
+++ b/src/features/webControls/components/WebControls.js
@@ -0,0 +1,239 @@
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react';
4import injectSheet from 'react-jss';
5import { Icon } from '@meetfranz/ui';
6import { defineMessages, intlShape } from 'react-intl';
7
8import {
9 mdiReload, mdiArrowRight, mdiArrowLeft, mdiHomeOutline, mdiEarth,
10} from '@mdi/js';
11
12const messages = defineMessages({
13 goHome: {
14 id: 'webControls.goHome',
15 defaultMessage: '!!!Home',
16 },
17 openInBrowser: {
18 id: 'webControls.openInBrowser',
19 defaultMessage: '!!!Open in Browser',
20 },
21 back: {
22 id: 'webControls.back',
23 defaultMessage: '!!!Back',
24 },
25 forward: {
26 id: 'webControls.forward',
27 defaultMessage: '!!!Forward',
28 },
29 reload: {
30 id: 'webControls.reload',
31 defaultMessage: '!!!Reload',
32 },
33});
34
35const styles = theme => ({
36 root: {
37 background: theme.colorBackground,
38 position: 'relative',
39 borderLeft: [1, 'solid', theme.todos.todosLayer.borderLeftColor],
40 zIndex: 300,
41 height: 50,
42 display: 'flex',
43 flexDirection: 'row',
44 alignItems: 'center',
45 padding: [0, 10],
46
47 '& + div': {
48 height: 'calc(100% - 50px)',
49 },
50 },
51 button: {
52 width: 30,
53 height: 50,
54 transition: 'opacity 0.25s',
55
56 '&:hover': {
57 opacity: 0.8,
58 },
59
60 '&:disabled': {
61 opacity: 0.5,
62 },
63 },
64 icon: {
65 width: '20px !important',
66 height: 20,
67 marginTop: 5,
68 },
69 input: {
70 marginBottom: 0,
71 height: 'auto',
72 margin: [0, 10],
73 flex: 1,
74 border: 0,
75 padding: [4, 10],
76 borderRadius: theme.borderRadius,
77 background: theme.inputBackground,
78 color: theme.inputColor,
79 },
80 inputButton: {
81 color: theme.colorText,
82 },
83});
84
85@injectSheet(styles) @observer
86class WebControls extends Component {
87 static propTypes = {
88 classes: PropTypes.object.isRequired,
89 goHome: PropTypes.func.isRequired,
90 canGoBack: PropTypes.bool.isRequired,
91 goBack: PropTypes.func.isRequired,
92 canGoForward: PropTypes.bool.isRequired,
93 goForward: PropTypes.func.isRequired,
94 reload: PropTypes.func.isRequired,
95 openInBrowser: PropTypes.func.isRequired,
96 url: PropTypes.string.isRequired,
97 navigate: PropTypes.func.isRequired,
98 }
99
100 static contextTypes = {
101 intl: intlShape,
102 };
103
104 static getDerivedStateFromProps(props, state) {
105 const { url } = props;
106 const { editUrl } = state;
107
108 if (!editUrl) {
109 return {
110 inputUrl: url,
111 editUrl: state.editUrl,
112 };
113 }
114 }
115
116 inputRef = React.createRef();
117
118 state = {
119 inputUrl: '',
120 editUrl: false,
121 }
122
123 render() {
124 const {
125 classes,
126 goHome,
127 canGoBack,
128 goBack,
129 canGoForward,
130 goForward,
131 reload,
132 openInBrowser,
133 url,
134 navigate,
135 } = this.props;
136
137 const {
138 inputUrl,
139 editUrl,
140 } = this.state;
141
142 const { intl } = this.context;
143
144 return (
145 <div className={classes.root}>
146 <button
147 onClick={goHome}
148 type="button"
149 className={classes.button}
150 data-tip={intl.formatMessage(messages.goHome)}
151 >
152 <Icon
153 icon={mdiHomeOutline}
154 className={classes.icon}
155 />
156 </button>
157 <button
158 onClick={goBack}
159 type="button"
160 className={classes.button}
161 disabled={!canGoBack}
162 data-tip={intl.formatMessage(messages.back)}
163 >
164 <Icon
165 icon={mdiArrowLeft}
166 className={classes.icon}
167 />
168 </button>
169 <button
170 onClick={goForward}
171 type="button"
172 className={classes.button}
173 disabled={!canGoForward}
174 data-tip={intl.formatMessage(messages.forward)}
175 >
176 <Icon
177 icon={mdiArrowRight}
178 className={classes.icon}
179 />
180 </button>
181 <button
182 onClick={reload}
183 type="button"
184 className={classes.button}
185 data-tip={intl.formatMessage(messages.reload)}
186 >
187 <Icon
188 icon={mdiReload}
189 className={classes.icon}
190 />
191 </button>
192 <input
193 value={editUrl ? inputUrl : url}
194 className={classes.input}
195 onChange={event => this.setState({
196 inputUrl: event.target.value,
197 })}
198 onFocus={(event) => {
199 event.target.select();
200 this.setState({
201 editUrl: true,
202 });
203 }}
204 onKeyDown={(event) => {
205 if (event.key === 'Enter') {
206 this.setState({
207 editUrl: false,
208 });
209 navigate(inputUrl);
210 this.inputRef.current.blur();
211 } else if (event.key === 'Escape') {
212 this.setState({
213 editUrl: false,
214 inputUrl: url,
215 });
216 event.target.blur();
217 }
218 }}
219 ref={this.inputRef}
220 />
221 <button
222 onClick={openInBrowser}
223 type="button"
224 className={classes.button}
225 data-tip={intl.formatMessage(messages.openInBrowser)}
226 data-place="left"
227 >
228 <Icon
229 icon={mdiEarth}
230 className={classes.icon}
231 />
232 </button>
233 {/* <ReactTooltip place="bottom" type="dark" effect="solid" /> */}
234 </div>
235 );
236 }
237}
238
239export default WebControls;