Browse Source

better link dialog

Artal Druk 8 years ago
parent
commit
290f6326c7
1 changed files with 77 additions and 23 deletions
  1. 77
    23
      src/RichTextEditor.js

+ 77
- 23
src/RichTextEditor.js View File

2
 import WebViewBridge from 'react-native-webview-bridge-updated';
2
 import WebViewBridge from 'react-native-webview-bridge-updated';
3
 import {InjectedMessageHandler} from './WebviewMessageHandler';
3
 import {InjectedMessageHandler} from './WebviewMessageHandler';
4
 import {actions, messages} from './const';
4
 import {actions, messages} from './const';
5
-import {Modal, View, Text, StyleSheet, TextInput, TouchableOpacity, Platform} from 'react-native';
5
+import {Modal, View, Text, StyleSheet, TextInput, TouchableOpacity, Platform, PixelRatio, Keyboard} from 'react-native';
6
 
6
 
7
 const injectScript = `
7
 const injectScript = `
8
   (function () {
8
   (function () {
10
   }());
10
   }());
11
 `;
11
 `;
12
 
12
 
13
+const PlatfomIOS = Platform.OS === 'ios';
14
+
13
 export default class RichTextEditor extends Component {
15
 export default class RichTextEditor extends Component {
14
   static propTypes = {
16
   static propTypes = {
15
     initialTitleHTML: PropTypes.string,
17
     initialTitleHTML: PropTypes.string,
25
     this._sendAction = this._sendAction.bind(this);
27
     this._sendAction = this._sendAction.bind(this);
26
     this.registerToolbar = this.registerToolbar.bind(this);
28
     this.registerToolbar = this.registerToolbar.bind(this);
27
     this.onBridgeMessage = this.onBridgeMessage.bind(this);
29
     this.onBridgeMessage = this.onBridgeMessage.bind(this);
30
+    this._onKeyboardWillShow = this._onKeyboardWillShow.bind(this);
31
+    this._onKeyboardWillHide = this._onKeyboardWillHide.bind(this);
28
     this.state = {
32
     this.state = {
29
       listeners: [],
33
       listeners: [],
30
       showLinkDialog: false,
34
       showLinkDialog: false,
31
       linkTitle: '',
35
       linkTitle: '',
32
-      linkUrl: ''
36
+      linkUrl: '',
37
+      keyboardHeight: 0
33
     };
38
     };
34
   }
39
   }
35
 
40
 
41
+  componentWillMount() {
42
+    if(PlatfomIOS) {
43
+      this.keyboardEventListeners = [
44
+        Keyboard.addListener('keyboardWillShow', this._onKeyboardWillShow),
45
+        Keyboard.addListener('keyboardWillHide', this._onKeyboardWillHide)
46
+      ];
47
+    } else {
48
+      this.keyboardEventListeners = [
49
+        Keyboard.addListener('keyboardDidShow', this._onKeyboardWillShow),
50
+        Keyboard.addListener('keyboardDidHide', this._onKeyboardWillHide)
51
+      ];
52
+    }
53
+  }
54
+
55
+  componentWillUnmount() {
56
+    this.keyboardEventListeners.forEach((eventListener) => eventListener.remove());
57
+  }
58
+
59
+  _onKeyboardWillShow(event) {
60
+    console.log('!!!!', event);
61
+    const newKeyboardHeight = event.endCoordinates.height;
62
+    if (this.state.keyboardHeight === newKeyboardHeight) {
63
+      return;
64
+    }
65
+    this.setState({keyboardHeight: newKeyboardHeight});
66
+  }
67
+
68
+  _onKeyboardWillHide(event) {
69
+    this.setState({keyboardHeight: 0});
70
+  }
71
+  
36
   onBridgeMessage(str){
72
   onBridgeMessage(str){
37
     try {
73
     try {
38
       const message = JSON.parse(str);
74
       const message = JSON.parse(str);
102
             onRequestClose={() => this.setState({showLinkDialog: false})}
138
             onRequestClose={() => this.setState({showLinkDialog: false})}
103
         >
139
         >
104
           <View style={styles.modal}>
140
           <View style={styles.modal}>
105
-
106
-
107
-            <View style={styles.innerModal}>
108
-
109
-              <Text>Title</Text>
141
+            <View style={[styles.innerModal, {marginBottom: this.state.keyboardHeight}]}>
142
+              <Text style={styles.inputTitle}>Title</Text>
110
               <View style={styles.inputWrapper}>
143
               <View style={styles.inputWrapper}>
111
                 <TextInput
144
                 <TextInput
112
                     style={{height: 20}}
145
                     style={{height: 20}}
114
                     value={this.state.linkTitle}
147
                     value={this.state.linkTitle}
115
                 />
148
                 />
116
               </View>
149
               </View>
117
-
118
-              <Text style={{marginTop: 10}}>URL</Text>
150
+              <Text style={[styles.inputTitle ,{marginTop: 10}]}>URL</Text>
119
               <View style={styles.inputWrapper}>
151
               <View style={styles.inputWrapper}>
120
                 <TextInput
152
                 <TextInput
121
                     style={{height: 20}}
153
                     style={{height: 20}}
123
                     value={this.state.linkUrl}
155
                     value={this.state.linkUrl}
124
                 />
156
                 />
125
               </View>
157
               </View>
126
-
158
+              {PlatfomIOS && <View style={styles.lineSeparator}/>}
127
               {this._renderModalButtons()}
159
               {this._renderModalButtons()}
128
             </View>
160
             </View>
129
           </View>
161
           </View>
140
   }
172
   }
141
 
173
 
142
   _renderModalButtons() {
174
   _renderModalButtons() {
175
+    const insertDisabled = this.state.linkTitle.length <= 0;
176
+    const containerPlatformStyle = PlatfomIOS ? {justifyContent: 'space-between'} : {paddingTop: 15};
177
+    const buttonPlatformStyle = PlatfomIOS ? {flex: 1, height: 45, justifyContent: 'center'} : {};
143
     return (
178
     return (
144
-      <View style={{paddingTop: 10, alignSelf: 'stretch', flexDirection: 'row'}}>
145
-        <View style={{flex: 1}}/>
179
+      <View style={[{alignSelf: 'stretch', flexDirection: 'row'}, containerPlatformStyle]}>
180
+        {!PlatfomIOS && <View style={{flex: 1}}/>}
146
         <TouchableOpacity
181
         <TouchableOpacity
147
             onPress={() => this._hideModal()}
182
             onPress={() => this._hideModal()}
183
+            style={buttonPlatformStyle}
148
         >
184
         >
149
           <Text style={[styles.button, {paddingRight: 10}]}>
185
           <Text style={[styles.button, {paddingRight: 10}]}>
150
-            Cancel
186
+            {PlatfomIOS ? 'Cancel' : 'CANCEL'}
151
           </Text>
187
           </Text>
152
         </TouchableOpacity>
188
         </TouchableOpacity>
153
         <TouchableOpacity
189
         <TouchableOpacity
155
               this.insertLink(this.state.linkUrl, this.state.linkTitle);
191
               this.insertLink(this.state.linkUrl, this.state.linkTitle);
156
               this._hideModal();
192
               this._hideModal();
157
             }}
193
             }}
194
+            disabled={insertDisabled}
195
+            style={buttonPlatformStyle}
158
         >
196
         >
159
-          <Text style={styles.button}>
160
-            OK
197
+          <Text style={[styles.button, {opacity: insertDisabled ? 0.5 : 1}]}>
198
+            {PlatfomIOS ? 'Insert' : 'INSERT'}
161
           </Text>
199
           </Text>
162
         </TouchableOpacity>
200
         </TouchableOpacity>
163
       </View>
201
       </View>
166
 
204
 
167
   render() {
205
   render() {
168
     //in release build, external html files in Android can't be required, so they must be placed in the assets folder and accessed via uri
206
     //in release build, external html files in Android can't be required, so they must be placed in the assets folder and accessed via uri
169
-    const pageSource = Platform.OS === 'ios' ? require('./editor.html') : { uri: 'file:///android_asset/editor.html' };
207
+    const pageSource = PlatfomIOS ? require('./editor.html') : { uri: 'file:///android_asset/editor.html' };
170
     return (
208
     return (
171
       <View style={{flex: 1}}>
209
       <View style={{flex: 1}}>
172
         <WebViewBridge
210
         <WebViewBridge
427
     backgroundColor: 'rgba(0, 0, 0, 0.5)'
465
     backgroundColor: 'rgba(0, 0, 0, 0.5)'
428
   },
466
   },
429
   innerModal: {
467
   innerModal: {
430
-    backgroundColor: '#ffffff',
431
-    padding: 20,
468
+    backgroundColor: 'rgba(255, 255, 255, 0.9)',
469
+    paddingTop: 20,
470
+    paddingBottom: PlatfomIOS ? 0 : 20,
471
+    paddingLeft: 20,
472
+    paddingRight: 20,
432
     alignSelf: 'stretch',
473
     alignSelf: 'stretch',
433
-    margin: 40
474
+    margin: 40,
475
+    borderRadius: PlatfomIOS ? 8 : 2
434
   },
476
   },
435
   button: {
477
   button: {
436
-    fontSize: 16
478
+    fontSize: 16,
479
+    color: '#4a4a4a',
480
+    textAlign: 'center'
437
   },
481
   },
438
   inputWrapper: {
482
   inputWrapper: {
439
-    marginTop: 10,
483
+    marginTop: 5,
440
     marginBottom: 10,
484
     marginBottom: 10,
441
-    borderBottomColor: '#000000',
442
-    borderBottomWidth: 1
485
+    borderBottomColor: '#4a4a4a',
486
+    borderBottomWidth: PlatfomIOS ? 1 / PixelRatio.get() : 0
487
+  },
488
+  inputTitle: {
489
+    color: '#4a4a4a'
490
+  },
491
+  lineSeparator: {
492
+    height: 1 / PixelRatio.get(),
493
+    backgroundColor: '#d5d5d5',
494
+    marginLeft: -20,
495
+    marginRight: -20,
496
+    marginTop: 20
443
   }
497
   }
444
 });
498
 });