diff options
Diffstat (limited to 'src/features/todos/components')
-rw-r--r-- | src/features/todos/components/TodosWebview.tsx (renamed from src/features/todos/components/TodosWebview.js) | 112 |
1 files changed, 64 insertions, 48 deletions
diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.tsx index 780864b91..3385ff74c 100644 --- a/src/features/todos/components/TodosWebview.js +++ b/src/features/todos/components/TodosWebview.tsx | |||
@@ -1,11 +1,10 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component, createRef, ReactElement, MouseEvent } from 'react'; |
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer } from 'mobx-react'; | 2 | import { observer } from 'mobx-react'; |
4 | import injectSheet from 'react-jss'; | 3 | import withStyles, { WithStylesProps } from 'react-jss'; |
5 | import Webview from 'react-electron-web-view'; | 4 | import Webview from 'react-electron-web-view'; |
6 | import classnames from 'classnames'; | 5 | import classnames from 'classnames'; |
7 | |||
8 | import { TODOS_PARTITION_ID } from '../../../config'; | 6 | import { TODOS_PARTITION_ID } from '../../../config'; |
7 | import { TodoClientMessage } from '../actions'; | ||
9 | 8 | ||
10 | const styles = theme => ({ | 9 | const styles = theme => ({ |
11 | root: { | 10 | root: { |
@@ -48,51 +47,71 @@ const styles = theme => ({ | |||
48 | }, | 47 | }, |
49 | }); | 48 | }); |
50 | 49 | ||
51 | class TodosWebview extends Component { | 50 | interface IProps extends WithStylesProps<typeof styles> { |
52 | static propTypes = { | 51 | isTodosServiceActive: boolean; |
53 | classes: PropTypes.object.isRequired, | 52 | isVisible: boolean; |
54 | isTodosServiceActive: PropTypes.bool.isRequired, | 53 | handleClientMessage: (channel: string, message: TodoClientMessage) => void; |
55 | isVisible: PropTypes.bool.isRequired, | 54 | setTodosWebview: (webView: Webview) => void; |
56 | handleClientMessage: PropTypes.func.isRequired, | 55 | resize: (newWidth: number) => void; |
57 | setTodosWebview: PropTypes.func.isRequired, | 56 | width: number; |
58 | resize: PropTypes.func.isRequired, | 57 | minWidth: number; |
59 | width: PropTypes.number.isRequired, | 58 | userAgent: string; |
60 | minWidth: PropTypes.number.isRequired, | 59 | todoUrl: string; |
61 | userAgent: PropTypes.string.isRequired, | 60 | isTodoUrlValid: boolean; |
62 | todoUrl: PropTypes.string.isRequired, | 61 | } |
63 | isTodoUrlValid: PropTypes.bool.isRequired, | 62 | |
64 | }; | 63 | interface IState { |
65 | 64 | isDragging: boolean; | |
66 | state = { | 65 | width: number; |
67 | isDragging: false, | 66 | initialPos: number; |
68 | width: 300, | 67 | delta: number; |
69 | }; | 68 | } |
69 | |||
70 | @observer | ||
71 | class TodosWebview extends Component<IProps, IState> { | ||
72 | private node = createRef<HTMLDivElement>(); | ||
73 | |||
74 | private webview: Webview; | ||
75 | |||
76 | constructor(props: IProps) { | ||
77 | super(props); | ||
78 | |||
79 | this.state = { | ||
80 | isDragging: false, | ||
81 | width: 300, | ||
82 | initialPos: 0, | ||
83 | delta: 0, | ||
84 | }; | ||
85 | this.resizePanel = this.resizePanel.bind(this); | ||
86 | this.stopResize = this.stopResize.bind(this); | ||
87 | } | ||
70 | 88 | ||
71 | componentDidMount() { | 89 | componentDidMount() { |
72 | this.setState({ | 90 | this.setState({ |
73 | width: this.props.width, | 91 | width: this.props.width, |
74 | }); | 92 | }); |
75 | 93 | ||
76 | this.node.addEventListener('mousemove', this.resizePanel.bind(this)); | 94 | if (this.node.current) { |
77 | this.node.addEventListener('mouseup', this.stopResize.bind(this)); | 95 | this.node.current.addEventListener('mousemove', this.resizePanel); |
78 | this.node.addEventListener('mouseleave', this.stopResize.bind(this)); | 96 | this.node.current.addEventListener('mouseup', this.stopResize); |
97 | this.node.current.addEventListener('mouseleave', this.stopResize); | ||
98 | } | ||
79 | } | 99 | } |
80 | 100 | ||
81 | startResize = event => { | 101 | startResize(e: MouseEvent<HTMLDivElement>): void { |
82 | this.setState({ | 102 | this.setState({ |
83 | isDragging: true, | 103 | isDragging: true, |
84 | initialPos: event.clientX, | 104 | initialPos: e.clientX, |
85 | delta: 0, | 105 | delta: 0, |
86 | }); | 106 | }); |
87 | }; | 107 | } |
88 | 108 | ||
89 | resizePanel(e) { | 109 | resizePanel(e: MouseEventInit): void { |
90 | const { minWidth } = this.props; | 110 | const { minWidth } = this.props; |
91 | |||
92 | const { isDragging, initialPos } = this.state; | 111 | const { isDragging, initialPos } = this.state; |
93 | 112 | ||
94 | if (isDragging && Math.abs(e.clientX - window.innerWidth) > minWidth) { | 113 | if (isDragging && Math.abs(e.clientX! - window.innerWidth) > minWidth) { |
95 | const delta = e.clientX - initialPos; | 114 | const delta = e.clientX! - initialPos; |
96 | 115 | ||
97 | this.setState({ | 116 | this.setState({ |
98 | delta, | 117 | delta, |
@@ -100,9 +119,8 @@ class TodosWebview extends Component { | |||
100 | } | 119 | } |
101 | } | 120 | } |
102 | 121 | ||
103 | stopResize() { | 122 | stopResize(): void { |
104 | const { resize, minWidth } = this.props; | 123 | const { resize, minWidth } = this.props; |
105 | |||
106 | const { isDragging, delta, width } = this.state; | 124 | const { isDragging, delta, width } = this.state; |
107 | 125 | ||
108 | if (isDragging) { | 126 | if (isDragging) { |
@@ -123,14 +141,17 @@ class TodosWebview extends Component { | |||
123 | } | 141 | } |
124 | 142 | ||
125 | startListeningToIpcMessages() { | 143 | startListeningToIpcMessages() { |
144 | if (!this.webview) { | ||
145 | return; | ||
146 | } | ||
147 | |||
126 | const { handleClientMessage } = this.props; | 148 | const { handleClientMessage } = this.props; |
127 | if (!this.webview) return; | ||
128 | this.webview.addEventListener('ipc-message', e => { | 149 | this.webview.addEventListener('ipc-message', e => { |
129 | handleClientMessage({ channel: e.channel, message: e.args[0] }); | 150 | handleClientMessage(e.channel, e.args[0]); |
130 | }); | 151 | }); |
131 | } | 152 | } |
132 | 153 | ||
133 | render() { | 154 | render(): ReactElement { |
134 | const { | 155 | const { |
135 | classes, | 156 | classes, |
136 | isTodosServiceActive, | 157 | isTodosServiceActive, |
@@ -141,10 +162,9 @@ class TodosWebview extends Component { | |||
141 | } = this.props; | 162 | } = this.props; |
142 | 163 | ||
143 | const { width, delta, isDragging } = this.state; | 164 | const { width, delta, isDragging } = this.state; |
144 | |||
145 | let displayedWidth = isVisible ? width : 0; | 165 | let displayedWidth = isVisible ? width : 0; |
146 | if (isTodosServiceActive) { | 166 | if (isTodosServiceActive) { |
147 | displayedWidth = null; | 167 | displayedWidth = 0; |
148 | } | 168 | } |
149 | 169 | ||
150 | return ( | 170 | return ( |
@@ -157,9 +177,7 @@ class TodosWebview extends Component { | |||
157 | })} | 177 | })} |
158 | style={{ width: displayedWidth }} | 178 | style={{ width: displayedWidth }} |
159 | onMouseUp={() => this.stopResize()} | 179 | onMouseUp={() => this.stopResize()} |
160 | ref={node => { | 180 | ref={this.node} |
161 | this.node = node; | ||
162 | }} | ||
163 | id="todos-panel" | 181 | id="todos-panel" |
164 | > | 182 | > |
165 | <div | 183 | <div |
@@ -168,7 +186,7 @@ class TodosWebview extends Component { | |||
168 | left: delta, | 186 | left: delta, |
169 | ...(isDragging ? { width: 600, marginLeft: -200 } : {}), | 187 | ...(isDragging ? { width: 600, marginLeft: -200 } : {}), |
170 | }} // This hack is required as resizing with webviews beneath behaves quite bad | 188 | }} // This hack is required as resizing with webviews beneath behaves quite bad |
171 | onMouseDown={e => this.startResize(e)} | 189 | onMouseDown={this.startResize} |
172 | /> | 190 | /> |
173 | {isDragging && ( | 191 | {isDragging && ( |
174 | <div | 192 | <div |
@@ -178,7 +196,7 @@ class TodosWebview extends Component { | |||
178 | )} | 196 | )} |
179 | {isTodoUrlValid && ( | 197 | {isTodoUrlValid && ( |
180 | <Webview | 198 | <Webview |
181 | className={classes.webview} | 199 | // className={classes.webview} // TODO - [TS DEBT] style not found |
182 | onDidAttach={() => { | 200 | onDidAttach={() => { |
183 | const { setTodosWebview } = this.props; | 201 | const { setTodosWebview } = this.props; |
184 | setTodosWebview(this.webview); | 202 | setTodosWebview(this.webview); |
@@ -198,6 +216,4 @@ class TodosWebview extends Component { | |||
198 | } | 216 | } |
199 | } | 217 | } |
200 | 218 | ||
201 | export default injectSheet(styles, { injectTheme: true })( | 219 | export default withStyles(styles, { injectTheme: true })(TodosWebview); |
202 | observer(TodosWebview), | ||
203 | ); | ||