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