ソースを参照

better link dialog

Artal Druk 8 年 前
コミット
290f6326c7
共有1 個のファイルを変更した77 個の追加23 個の削除を含む
  1. 77
    23
      src/RichTextEditor.js

+ 77
- 23
src/RichTextEditor.js ファイルの表示

@@ -2,7 +2,7 @@ import React, {Component, PropTypes} from 'react';
2 2
 import WebViewBridge from 'react-native-webview-bridge-updated';
3 3
 import {InjectedMessageHandler} from './WebviewMessageHandler';
4 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 7
 const injectScript = `
8 8
   (function () {
@@ -10,6 +10,8 @@ const injectScript = `
10 10
   }());
11 11
 `;
12 12
 
13
+const PlatfomIOS = Platform.OS === 'ios';
14
+
13 15
 export default class RichTextEditor extends Component {
14 16
   static propTypes = {
15 17
     initialTitleHTML: PropTypes.string,
@@ -25,14 +27,48 @@ export default class RichTextEditor extends Component {
25 27
     this._sendAction = this._sendAction.bind(this);
26 28
     this.registerToolbar = this.registerToolbar.bind(this);
27 29
     this.onBridgeMessage = this.onBridgeMessage.bind(this);
30
+    this._onKeyboardWillShow = this._onKeyboardWillShow.bind(this);
31
+    this._onKeyboardWillHide = this._onKeyboardWillHide.bind(this);
28 32
     this.state = {
29 33
       listeners: [],
30 34
       showLinkDialog: false,
31 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 72
   onBridgeMessage(str){
37 73
     try {
38 74
       const message = JSON.parse(str);
@@ -102,11 +138,8 @@ export default class RichTextEditor extends Component {
102 138
             onRequestClose={() => this.setState({showLinkDialog: false})}
103 139
         >
104 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 143
               <View style={styles.inputWrapper}>
111 144
                 <TextInput
112 145
                     style={{height: 20}}
@@ -114,8 +147,7 @@ export default class RichTextEditor extends Component {
114 147
                     value={this.state.linkTitle}
115 148
                 />
116 149
               </View>
117
-
118
-              <Text style={{marginTop: 10}}>URL</Text>
150
+              <Text style={[styles.inputTitle ,{marginTop: 10}]}>URL</Text>
119 151
               <View style={styles.inputWrapper}>
120 152
                 <TextInput
121 153
                     style={{height: 20}}
@@ -123,7 +155,7 @@ export default class RichTextEditor extends Component {
123 155
                     value={this.state.linkUrl}
124 156
                 />
125 157
               </View>
126
-
158
+              {PlatfomIOS && <View style={styles.lineSeparator}/>}
127 159
               {this._renderModalButtons()}
128 160
             </View>
129 161
           </View>
@@ -140,14 +172,18 @@ export default class RichTextEditor extends Component {
140 172
   }
141 173
 
142 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 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 181
         <TouchableOpacity
147 182
             onPress={() => this._hideModal()}
183
+            style={buttonPlatformStyle}
148 184
         >
149 185
           <Text style={[styles.button, {paddingRight: 10}]}>
150
-            Cancel
186
+            {PlatfomIOS ? 'Cancel' : 'CANCEL'}
151 187
           </Text>
152 188
         </TouchableOpacity>
153 189
         <TouchableOpacity
@@ -155,9 +191,11 @@ export default class RichTextEditor extends Component {
155 191
               this.insertLink(this.state.linkUrl, this.state.linkTitle);
156 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 199
           </Text>
162 200
         </TouchableOpacity>
163 201
       </View>
@@ -166,7 +204,7 @@ export default class RichTextEditor extends Component {
166 204
 
167 205
   render() {
168 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 208
     return (
171 209
       <View style={{flex: 1}}>
172 210
         <WebViewBridge
@@ -427,18 +465,34 @@ const styles = StyleSheet.create({
427 465
     backgroundColor: 'rgba(0, 0, 0, 0.5)'
428 466
   },
429 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 473
     alignSelf: 'stretch',
433
-    margin: 40
474
+    margin: 40,
475
+    borderRadius: PlatfomIOS ? 8 : 2
434 476
   },
435 477
   button: {
436
-    fontSize: 16
478
+    fontSize: 16,
479
+    color: '#4a4a4a',
480
+    textAlign: 'center'
437 481
   },
438 482
   inputWrapper: {
439
-    marginTop: 10,
483
+    marginTop: 5,
440 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
 });