Skip to content

Commit 409fb68

Browse files
committed
Implement basic UI of NewTopicPage
1 parent 1cbb280 commit 409fb68

File tree

8 files changed

+220
-2
lines changed

8 files changed

+220
-2
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"react-native-gifted-listview": "BelinChung/react-native-gifted-listview#a64c4a5d66",
2020
"react-native-htmlview": "^0.5.0",
2121
"react-native-root-toast": "^1.0.3",
22-
"react-native-router-flux": "^3.31.0",
22+
"react-native-router-flux": "^3.35.0",
2323
"react-native-vector-icons": "^2.0.3",
2424
"react-native-viewpager": "^0.2.11",
2525
"react-redux": "^4.4.5",
458 Bytes
Loading
840 Bytes
Loading
1012 Bytes
Loading
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React, {Component, PropTypes} from 'react';
2+
import {View, Text, Image} from 'react-native';
3+
4+
import Style from '../../utilities/style';
5+
import NewTopicIconImg from '../assets/new_topic_icon.png';
6+
7+
class NewTopicButton extends Component {
8+
static defaultProps = {};
9+
static propTypes = {
10+
onPress: PropTypes.func.isRequired
11+
};
12+
state = {};
13+
14+
constructor(props) {
15+
super(props);
16+
}
17+
18+
render() {
19+
return (
20+
<View>
21+
<Image style={styles.image} source={NewTopicIconImg} />
22+
</View>
23+
);
24+
}
25+
26+
}
27+
28+
const styles = Style.create({
29+
image: {
30+
width: 25,
31+
height: 25,
32+
}
33+
});
34+
35+
36+
export default NewTopicButton;
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
import React, {Component, PropTypes} from 'react';
2+
import {View, Text, TextInput, TouchableOpacity} from 'react-native';
3+
import {Actions} from 'react-native-router-flux';
4+
import Icon from 'react-native-vector-icons/FontAwesome';
5+
6+
import Style from '../../../utilities/style';
7+
import NodeListManager from '../../../utilities/node_list_manager';
8+
import PageContainer from '../../common/PageContainer';
9+
10+
class NewTopicPage extends Component {
11+
static propTypes = {
12+
nodeSlug: PropTypes.string,
13+
};
14+
state = {
15+
nodeName: '问与答(默认)',
16+
nodeSlug: 'qna',
17+
};
18+
19+
constructor(props) {
20+
super(props);
21+
}
22+
23+
componentDidMount() {
24+
this.setUpNavigationBar();
25+
this.setUpNode();
26+
}
27+
28+
setUpNode = () => {
29+
const { nodeSlug } = this.props;
30+
if (nodeSlug) {
31+
NodeListManager.getNodes().then(nodes => {
32+
const filteredNodes = nodes.filter((node) => {
33+
const { slug, name } = node;
34+
if (slug && name && (slug.toLowerCase().indexOf(nodeSlug) > -1 || name.toLowerCase().indexOf(nodeSlug) > -1)) {
35+
return true;
36+
} else {
37+
return false;
38+
}
39+
});
40+
if (filteredNodes.length > 0) {
41+
const currentNode = filteredNodes[0];
42+
const { slug, name } = currentNode;
43+
this.setState({ nodeName: name, nodeSlug: slug });
44+
} else {
45+
this.setState({ nodeName: '(未知)', nodeSlug: null });
46+
}
47+
}, error => {
48+
alert('Error getting nodes:' + error);
49+
});
50+
}
51+
};
52+
53+
setUpNavigationBar = () => {
54+
Actions.refresh({
55+
rightTitle: '发布',
56+
onRight: this.onRightButtonPress,
57+
rightButtonTextStyle: { color: 'white' },
58+
});
59+
};
60+
61+
onRightButtonPress = () => {
62+
this.refs['titleTextInput'].blur();
63+
this.refs['contentTextInput'].blur();
64+
};
65+
66+
async requestOnceCode() {
67+
// TODO: Implement get once code: $('input[name="once"]')
68+
}
69+
70+
render() {
71+
const { nodeName } = this.state;
72+
return (
73+
<PageContainer>
74+
<View style={styles.nodeSelectorWrapper}>
75+
<Text style={styles.nodeSelectorTitle}>节点:</Text>
76+
<TouchableOpacity style={styles.nodeSelectorTouchable}>
77+
<View style={styles.nodeSelectorTouchableInnerWrapper}>
78+
<Text style={styles.nodeSelectorText}>{nodeName}</Text>
79+
<Icon style={styles.nodeSelectorIcon} size={13} name="chevron-right" color="#329EED" />
80+
</View>
81+
</TouchableOpacity>
82+
</View>
83+
<View style={styles.titleTextInputWrapper}>
84+
<TextInput
85+
ref="titleTextInput"
86+
returnKeyType="next"
87+
style={styles.titleTextInput}
88+
onSubmitEditing={this.onTitleTextInputSubmit}
89+
placeholder="标题" />
90+
</View>
91+
<View style={styles.contentTextInputWrapper}>
92+
<TextInput
93+
ref="contentTextInput"
94+
style={styles.contentTextInput}
95+
multiline={true}
96+
placeholder="内容" />
97+
</View>
98+
</PageContainer>
99+
);
100+
}
101+
102+
onTitleTextInputSubmit = () => {
103+
this.refs['contentTextInput'].focus();
104+
};
105+
106+
}
107+
108+
const styles = Style.create({
109+
nodeSelectorWrapper: {
110+
backgroundColor: '#F7F8F9',
111+
height: 40,
112+
borderBottomColor: '#D8D8D8',
113+
borderBottomWidth: 1,
114+
alignItems: 'center',
115+
paddingLeft: 12,
116+
paddingRight: 12,
117+
flexDirection: 'row',
118+
},
119+
nodeSelectorText: {
120+
color: '#329EED',
121+
fontSize: 14,
122+
flex: 1,
123+
},
124+
nodeSelectorTitle: {
125+
color: '#A4A4A4',
126+
fontSize: 14,
127+
128+
},
129+
nodeSelectorTouchable: {
130+
flex: 1,
131+
},
132+
nodeSelectorTouchableInnerWrapper: {
133+
flexDirection: 'row',
134+
},
135+
nodeSelectorIcon: {
136+
marginTop: 2,
137+
},
138+
139+
titleTextInputWrapper: {
140+
borderBottomWidth: 1,
141+
borderBottomColor: '#D8E0E4',
142+
marginLeft: 12,
143+
marginRight: 12,
144+
marginTop: 10,
145+
},
146+
titleTextInput: {
147+
flex: 1,
148+
height: 25,
149+
fontSize: 16,
150+
},
151+
152+
contentTextInputWrapper: {
153+
flex: 1,
154+
marginLeft: 12,
155+
marginRight: 12,
156+
marginTop: 10,
157+
marginBottom: 12,
158+
},
159+
contentTextInput: {
160+
flex: 1,
161+
fontSize: 14,
162+
},
163+
});
164+
165+
export default NewTopicPage;

src/components/pages/Node/index.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import React, {Component, PropTypes} from 'react';
2+
import {Actions} from 'react-native-router-flux';
23

34
import Style from '../../../utilities/style';
45
import TopicList from '../../common/TopicList';
56
import PageContainer from '../../common/PageContainer';
7+
import NewTopicButton from '../../common/NewTopicButton';
8+
9+
import NewTopicButtonImage from '../../assets/new_topic_icon.png';
610

711
class NodePage extends Component {
812
static propTypes = {
@@ -15,14 +19,25 @@ class NodePage extends Component {
1519
}
1620

1721
render() {
18-
const {slug} = this.props;
22+
const { slug } = this.props;
1923
return (
2024
<PageContainer>
2125
<TopicList isNode={true} slug={slug} />
2226
</PageContainer>
2327
);
2428
}
2529

30+
componentDidMount() {
31+
Actions.refresh({
32+
rightButtonImage: NewTopicButtonImage,
33+
onRight: this.onNewTopicButtonPress
34+
});
35+
}
36+
37+
onNewTopicButtonPress = () => {
38+
Actions.newTopic({ nodeSlug: this.props.slug });
39+
}
40+
2641
}
2742

2843
export default NodePage;

src/containers/App.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import UserTopicPageContainer from './UserTopicPage';
1818
import NodeListPage from '../components/pages/NodeList';
1919
import NodePage from '../components/pages/Node';
2020
import LoginPage from '../components/pages/Login';
21+
import NewTopicPage from '../components/pages/NewTopic';
2122

2223
const store = configureStore();
2324

@@ -66,6 +67,7 @@ class App extends Component {
6667
<Scene key="user_topic" component={UserTopicPageContainer} title="用户话题" />
6768
<Scene key="node" component={NodePage} title="节点" />
6869
<Scene key="login" component={LoginPage} direction="vertical" hideNavBar={true} />
70+
<Scene key="newTopic" component={NewTopicPage} title="创建话题" />
6971
</Scene>
7072
</RouterWithRedux>
7173
</Provider>

0 commit comments

Comments
 (0)