diff options
author | 2019-07-30 11:41:54 +0200 | |
---|---|---|
committer | 2019-07-30 11:41:54 +0200 | |
commit | d7ed456a7b6f73e046ba3a2ef38eb21f82f06ca4 (patch) | |
tree | f24f4f39ae38bdfdd581f451fc3e2e79f5670df5 /src/features/todos/components | |
parent | Fix position of todos app (diff) | |
download | ferdium-app-d7ed456a7b6f73e046ba3a2ef38eb21f82f06ca4.tar.gz ferdium-app-d7ed456a7b6f73e046ba3a2ef38eb21f82f06ca4.tar.zst ferdium-app-d7ed456a7b6f73e046ba3a2ef38eb21f82f06ca4.zip |
Make todo layer resizable
Diffstat (limited to 'src/features/todos/components')
-rw-r--r-- | src/features/todos/components/TodosWebview.js | 129 |
1 files changed, 118 insertions, 11 deletions
diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js index ca0b94ea1..1d99b9388 100644 --- a/src/features/todos/components/TodosWebview.js +++ b/src/features/todos/components/TodosWebview.js | |||
@@ -8,15 +8,26 @@ import * as environment from '../../../environment'; | |||
8 | const styles = theme => ({ | 8 | const styles = theme => ({ |
9 | root: { | 9 | root: { |
10 | background: theme.colorBackground, | 10 | background: theme.colorBackground, |
11 | height: '100%', | 11 | position: 'relative', |
12 | width: 300, | ||
13 | position: 'absolute', | ||
14 | top: 0, | ||
15 | right: -300, | ||
16 | }, | 12 | }, |
17 | webview: { | 13 | webview: { |
18 | height: '100%', | 14 | height: '100%', |
19 | }, | 15 | }, |
16 | resizeHandler: { | ||
17 | position: 'absolute', | ||
18 | left: 0, | ||
19 | marginLeft: -5, | ||
20 | width: 10, | ||
21 | zIndex: 400, | ||
22 | cursor: 'col-resize', | ||
23 | }, | ||
24 | dragIndicator: { | ||
25 | position: 'absolute', | ||
26 | left: 0, | ||
27 | width: 5, | ||
28 | zIndex: 400, | ||
29 | background: theme.todos.dragIndicator.background, | ||
30 | }, | ||
20 | }); | 31 | }); |
21 | 32 | ||
22 | @injectSheet(styles) @observer | 33 | @injectSheet(styles) @observer |
@@ -24,17 +35,113 @@ class TodosWebview extends Component { | |||
24 | static propTypes = { | 35 | static propTypes = { |
25 | classes: PropTypes.object.isRequired, | 36 | classes: PropTypes.object.isRequired, |
26 | authToken: PropTypes.string.isRequired, | 37 | authToken: PropTypes.string.isRequired, |
38 | resize: PropTypes.func.isRequired, | ||
39 | width: PropTypes.number.isRequired, | ||
40 | minWidth: PropTypes.number.isRequired, | ||
27 | }; | 41 | }; |
28 | 42 | ||
43 | state = { | ||
44 | isDragging: false, | ||
45 | width: 300, | ||
46 | } | ||
47 | |||
48 | componentWillMount() { | ||
49 | const { width } = this.props; | ||
50 | |||
51 | this.setState({ | ||
52 | width, | ||
53 | }); | ||
54 | } | ||
55 | |||
56 | componentDidMount() { | ||
57 | this.node.addEventListener('mousemove', this.resizePanel.bind(this)); | ||
58 | this.node.addEventListener('mouseup', this.stopResize.bind(this)); | ||
59 | this.node.addEventListener('mouseleave', this.stopResize.bind(this)); | ||
60 | } | ||
61 | |||
62 | startResize = (event) => { | ||
63 | this.setState({ | ||
64 | isDragging: true, | ||
65 | initialPos: event.clientX, | ||
66 | delta: 0, | ||
67 | }); | ||
68 | } | ||
69 | |||
70 | resizePanel(e) { | ||
71 | const { minWidth } = this.props; | ||
72 | |||
73 | const { | ||
74 | isDragging, | ||
75 | initialPos, | ||
76 | } = this.state; | ||
77 | |||
78 | if (isDragging && Math.abs(e.clientX - window.innerWidth) > minWidth) { | ||
79 | const delta = e.clientX - initialPos; | ||
80 | |||
81 | this.setState({ | ||
82 | delta, | ||
83 | }); | ||
84 | } | ||
85 | } | ||
86 | |||
87 | stopResize() { | ||
88 | const { | ||
89 | resize, | ||
90 | minWidth, | ||
91 | } = this.props; | ||
92 | |||
93 | const { | ||
94 | isDragging, | ||
95 | delta, | ||
96 | width, | ||
97 | } = this.state; | ||
98 | |||
99 | if (isDragging) { | ||
100 | let newWidth = width + (delta < 0 ? Math.abs(delta) : -Math.abs(delta)); | ||
101 | |||
102 | if (newWidth < minWidth) { | ||
103 | newWidth = minWidth; | ||
104 | } | ||
105 | |||
106 | this.setState({ | ||
107 | isDragging: false, | ||
108 | delta: 0, | ||
109 | width: newWidth, | ||
110 | }); | ||
111 | |||
112 | resize(newWidth); | ||
113 | } | ||
114 | } | ||
115 | |||
29 | render() { | 116 | render() { |
30 | const { authToken, classes } = this.props; | 117 | const { authToken, classes } = this.props; |
118 | const { width, delta, isDragging } = this.state; | ||
119 | |||
31 | return ( | 120 | return ( |
32 | <div className={classes.root}> | 121 | <> |
33 | <Webview | 122 | <div |
34 | className={classes.webview} | 123 | className={classes.root} |
35 | src={`${environment.TODOS_FRONTEND}?authToken=${authToken}`} | 124 | style={{ width }} |
36 | /> | 125 | onMouseUp={() => this.stopResize()} |
37 | </div> | 126 | ref={(node) => { this.node = node; }} |
127 | > | ||
128 | <div | ||
129 | className={classes.resizeHandler} | ||
130 | style={Object.assign({ left: delta }, isDragging ? { width: 600, marginLeft: -200 } : {})} // This hack is required as resizing with webviews beneath behaves quite bad | ||
131 | onMouseDown={e => this.startResize(e)} | ||
132 | /> | ||
133 | {isDragging && ( | ||
134 | <div | ||
135 | className={classes.dragIndicator} | ||
136 | style={{ left: delta }} // This hack is required as resizing with webviews beneath behaves quite bad | ||
137 | /> | ||
138 | )} | ||
139 | <Webview | ||
140 | className={classes.webview} | ||
141 | src={`${environment.TODOS_FRONTEND}?authToken=${authToken}`} | ||
142 | /> | ||
143 | </div> | ||
144 | </> | ||
38 | ); | 145 | ); |
39 | } | 146 | } |
40 | } | 147 | } |