Skip to content

Commit 6a92aa8

Browse files
committed
create new posts from the app
1 parent 4aee4f0 commit 6a92aa8

File tree

13 files changed

+245
-7
lines changed

13 files changed

+245
-7
lines changed

App/Actions/PostActions.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@ var PostActions = {
1515
});
1616
}
1717
});
18+
},
19+
20+
createPost: function(content, callback) {
21+
PostService.createPost(content, function(error, postProps) {
22+
if(callback) callback(error);
23+
24+
if (!error) {
25+
Dispatcher.dispatch({
26+
actionType: AppConstants.POST_ADDED,
27+
postProps: postProps
28+
});
29+
}
30+
});
1831
}
1932
};
2033

App/Api/PostService.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
var client = require('../Api/HTTPClient')
22

33
var PostService = {
4-
parsePost: function(data) {
4+
parsePost: function(response) {
5+
if (!response) return null;
6+
57
return {
6-
id: data.id,
7-
content: data.content
8+
id: response.id,
9+
content: response.content,
10+
username: response.username
811
};
912
},
1013

@@ -24,7 +27,14 @@ var PostService = {
2427
var listProps = PostService.parsePosts(response);
2528
callback(error, listProps);
2629
});
27-
}
30+
},
31+
32+
createPost: function(content, callback) {
33+
client.post("api/posts", {content: content}, function(error, response) {
34+
var postProps = PostService.parsePost(response);
35+
callback(error, postProps);
36+
});
37+
},
2838
};
2939

3040
module.exports = PostService;

App/Components/TextInput.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
var React = require('react-native')
2+
3+
var {
4+
PixelRatio
5+
} = React;
6+
7+
var cssVar = require('../Lib/cssVar');
8+
9+
var TextInput = React.createClass({
10+
propTypes: React.TextInput.propTypes,
11+
12+
setNativeProps() {
13+
var input = this.refs.input;
14+
input.setNativeProps.apply(input, arguments);
15+
},
16+
render() {
17+
return (
18+
<React.TextInput
19+
{...this.props}
20+
ref="input"
21+
style={[styles.input, this.props.style || {}]}
22+
/>
23+
);
24+
}
25+
})
26+
27+
var styles = React.StyleSheet.create({
28+
input: {
29+
borderWidth: 1 / PixelRatio.get(),
30+
borderColor: cssVar('gray50'),
31+
padding: 10,
32+
fontFamily: cssVar('fontRegular'),
33+
color: cssVar('gray90'),
34+
fontSize: 8 // make it small to know it's not set
35+
}
36+
});
37+
38+
module.exports = TextInput;

App/Constants/AppConstants.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ module.exports = keyMirror({
99
LAUNCH_ROUTE_PATH: null,
1010
NETWORK_ACTIVITY: null,
1111
NAVBAR_UPDATE: null,
12-
POST_LIST_UPDATED: null
12+
POST_LIST_UPDATED: null,
13+
POST_ADDED: null
1314
});

App/Lib/CSSVarConfig.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ var {
77

88
module.exports = {
99
gray90: '#323A3B',
10+
gray50: '#828A8B',
1011
gray30: '#B4B9B9',
1112
gray20: '#CFD2D3',
1213
gray10: '#EBECEC',

App/Mixins/AuthHelper.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ var React = require('react-native');
22
var {
33
View,
44
StyleSheet,
5-
TextInput,
65
PixelRatio,
76
TouchableWithoutFeedback
87
} = React;
@@ -12,6 +11,7 @@ var cssVar = require('../Lib/cssVar');
1211
var AppActions = require('../Actions/AppActions');
1312
var Text = require('../Components/Text');
1413
var Button = require('../Components/Button');
14+
var TextInput = require('../Components/TextInput');
1515

1616
var AuthHelper = {
1717

App/Mixins/KeyboardListener.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
var React = require('react-native');
2+
var KeyboardEvents = require('react-native-keyboardevents');
3+
var KeyboardEventEmitter = KeyboardEvents.Emitter;
4+
5+
var KeyboardListener = {
6+
getInitialState: function() {
7+
return {
8+
keyboardSpace: 0
9+
};
10+
},
11+
12+
isKeyboardVisible: function() {
13+
return this.state.keyboardSpace > 0;
14+
},
15+
16+
updateKeyboardSpace: function(frames) {
17+
if (this.isMounted() && frames && frames.end) {
18+
this.setState({keyboardSpace: frames.end.height});
19+
}
20+
},
21+
22+
resetKeyboardSpace: function() {
23+
if (this.isMounted()) {
24+
this.setState({keyboardSpace: 0});
25+
}
26+
},
27+
28+
componentDidMount: function() {
29+
KeyboardEventEmitter.on(KeyboardEvents.KeyboardDidShowEvent, this.updateKeyboardSpace);
30+
KeyboardEventEmitter.on(KeyboardEvents.KeyboardWillHideEvent, this.resetKeyboardSpace);
31+
},
32+
33+
componentWillUnmount: function() {
34+
KeyboardEventEmitter.off(KeyboardEvents.KeyboardDidShowEvent, this.updateKeyboardSpace);
35+
KeyboardEventEmitter.off(KeyboardEvents.KeyboardWillHideEvent, this.resetKeyboardSpace);
36+
},
37+
};
38+
39+
module.exports = KeyboardListener;

App/Navigation/Router.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ var LoggedIn = {
4343
switch(path) {
4444
case 'settings':
4545
return Routes.Settings();
46+
case 'post':
47+
return Routes.CreatePost();
4648
default:
4749
return null;
4850
};

App/Navigation/Routes.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@ var Routes = {
1818
return {
1919
component: require('../Screens/Dashboard/Dashboard'),
2020
title: 'Dashboard',
21-
navRight: {
21+
navLeft: {
2222
subPath: 'settings',
2323
label: 'Me' // TODO: icon font
24+
},
25+
navRight: {
26+
subPath: 'post',
27+
label: '+' // TODO: icon font
2428
}
2529
};
2630
},
@@ -31,6 +35,16 @@ var Routes = {
3135
title: 'Settings'
3236
};
3337
},
38+
39+
CreatePost: function() {
40+
return {
41+
component: require('../Screens/CreatePost'),
42+
title: 'New Post',
43+
navBack: {
44+
label: 'Cancel'
45+
}
46+
};
47+
},
3448
};
3549

3650
module.exports = Routes;

App/Screens/CreatePost.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
var React = require('react-native');
2+
var {
3+
View,
4+
StyleSheet
5+
} = React;
6+
7+
var TextInput = require('../Components/TextInput');
8+
var Button = require('../Components/Button');
9+
var PostActions = require('../Actions/PostActions');
10+
var AppActions = require('../Actions/AppActions');
11+
12+
var KeyboardListener = require('../Mixins/KeyboardListener');
13+
14+
var CreatePost = React.createClass({
15+
mixins: [KeyboardListener],
16+
17+
getInitialState: function() {
18+
return {
19+
content: ''
20+
};
21+
},
22+
23+
onSubmitButton: function() {
24+
PostActions.createPost(this.state.content, function(error) {
25+
if (error) {
26+
// TODO: better error handling
27+
alert(error.message);
28+
}
29+
else {
30+
AppActions.goBack(this.props.navigator);
31+
}
32+
}.bind(this));
33+
},
34+
35+
render: function() {
36+
return (
37+
<View style={styles.flex}>
38+
<TextInput ref="content"
39+
placeholder={"What do you have to say for yourself?"}
40+
keyboardType="default"
41+
multiline={true}
42+
autoFocus={true}
43+
style={styles.input}
44+
enablesReturnKeyAutomatically={true}
45+
returnKeyType='done'
46+
onChange={(event) => this.state.content = event.nativeEvent.text }
47+
/>
48+
<View style={styles.footer}>
49+
<View style={styles.flex} />
50+
<Button type='blue' style={styles.button} onPress={this.onSubmitButton}>
51+
Submit
52+
</Button>
53+
</View>
54+
<View style={{height: this.state.keyboardSpace}}></View>
55+
</View>
56+
);
57+
}
58+
});
59+
60+
var styles = StyleSheet.create({
61+
flex: {
62+
flex: 1
63+
},
64+
input: {
65+
flex: 1,
66+
fontSize: 16,
67+
backgroundColor: 'white',
68+
padding: 20
69+
},
70+
button: {
71+
// width: 150
72+
},
73+
footer: {
74+
padding: 10,
75+
flexDirection: 'row'
76+
}
77+
});
78+
79+
module.exports = CreatePost;

App/Stores/PostListStore.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ var CHANGE_EVENT = 'change';
1010
// TODO: Immutable?
1111
var _hash = {};
1212

13+
function addModel(key, props) {
14+
if(!_hash[key]) _hash[key] = [];
15+
var model = new Post(props);
16+
_hash[key].unshift(model);
17+
}
18+
1319
function setList(key, list) {
1420
var models = [];
1521
for(var i in list) {
@@ -44,6 +50,10 @@ Dispatcher.register(function(action) {
4450
setList(action.listProps.username, action.listProps.posts);
4551
ModelStore.emitChange(action.listProps.username);
4652
break;
53+
case AppConstants.POST_ADDED:
54+
addModel(action.postProps.username, action.postProps);
55+
ModelStore.emitChange(action.postProps.username);
56+
break;
4757
// TODO: save
4858
default:
4959
// no op

ios/Sample.xcodeproj/project.pbxproj

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
2525
684860A3F12E466838065EED /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A565388F7CDBDB0548B5DC8D /* libPods.a */; };
2626
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
27+
D339AEF21BAA809100CFA651 /* libRNKeyboardEvents.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D339AEF01BAA808800CFA651 /* libRNKeyboardEvents.a */; };
2728
D374ADC51BA929C500453203 /* libRNKeychain.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D374ADC41BA929BA00453203 /* libRNKeychain.a */; };
2829
D374ADD31BA9336E00453203 /* EnvironmentManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D374ADD21BA9336E00453203 /* EnvironmentManager.m */; };
2930
/* End PBXBuildFile section */
@@ -106,6 +107,13 @@
106107
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
107108
remoteInfo = RCTText;
108109
};
110+
D339AEEF1BAA808800CFA651 /* PBXContainerItemProxy */ = {
111+
isa = PBXContainerItemProxy;
112+
containerPortal = D339AEE11BAA808800CFA651 /* RNKeyboardEvents.xcodeproj */;
113+
proxyType = 2;
114+
remoteGlobalIDString = F12AFB9B1ADAF8F800E0535D;
115+
remoteInfo = RNKeyboardEvents;
116+
};
109117
D374ADC31BA929BA00453203 /* PBXContainerItemProxy */ = {
110118
isa = PBXContainerItemProxy;
111119
containerPortal = D374ADB51BA929B900453203 /* RNKeychain.xcodeproj */;
@@ -139,6 +147,7 @@
139147
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
140148
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
141149
A565388F7CDBDB0548B5DC8D /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
150+
D339AEE11BAA808800CFA651 /* RNKeyboardEvents.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNKeyboardEvents.xcodeproj; path = "../node_modules/react-native-keyboardevents/RNKeyboardEvents.xcodeproj"; sourceTree = "<group>"; };
142151
D374ADB51BA929B900453203 /* RNKeychain.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNKeychain.xcodeproj; path = "../node_modules/react-native-keychain/RNKeychain.xcodeproj"; sourceTree = "<group>"; };
143152
D374ADD21BA9336E00453203 /* EnvironmentManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EnvironmentManager.m; path = Sample/EnvironmentManager.m; sourceTree = "<group>"; };
144153
F8DE0F0169FA03E7C6B1C51E /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
@@ -156,6 +165,7 @@
156165
isa = PBXFrameworksBuildPhase;
157166
buildActionMask = 2147483647;
158167
files = (
168+
D339AEF21BAA809100CFA651 /* libRNKeyboardEvents.a in Frameworks */,
159169
D374ADC51BA929C500453203 /* libRNKeychain.a in Frameworks */,
160170
146834051AC3E58100842450 /* libReact.a in Frameworks */,
161171
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
@@ -298,6 +308,7 @@
298308
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
299309
isa = PBXGroup;
300310
children = (
311+
D339AEE11BAA808800CFA651 /* RNKeyboardEvents.xcodeproj */,
301312
D374ADB51BA929B900453203 /* RNKeychain.xcodeproj */,
302313
146833FF1AC3E56700842450 /* React.xcodeproj */,
303314
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */,
@@ -344,6 +355,14 @@
344355
name = Products;
345356
sourceTree = "<group>";
346357
};
358+
D339AEE21BAA808800CFA651 /* Products */ = {
359+
isa = PBXGroup;
360+
children = (
361+
D339AEF01BAA808800CFA651 /* libRNKeyboardEvents.a */,
362+
);
363+
name = Products;
364+
sourceTree = "<group>";
365+
};
347366
D374ADB61BA929B900453203 /* Products */ = {
348367
isa = PBXGroup;
349368
children = (
@@ -459,6 +478,10 @@
459478
ProductGroup = 146834001AC3E56700842450 /* Products */;
460479
ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
461480
},
481+
{
482+
ProductGroup = D339AEE21BAA808800CFA651 /* Products */;
483+
ProjectRef = D339AEE11BAA808800CFA651 /* RNKeyboardEvents.xcodeproj */;
484+
},
462485
{
463486
ProductGroup = D374ADB61BA929B900453203 /* Products */;
464487
ProjectRef = D374ADB51BA929B900453203 /* RNKeychain.xcodeproj */;
@@ -543,6 +566,13 @@
543566
remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */;
544567
sourceTree = BUILT_PRODUCTS_DIR;
545568
};
569+
D339AEF01BAA808800CFA651 /* libRNKeyboardEvents.a */ = {
570+
isa = PBXReferenceProxy;
571+
fileType = archive.ar;
572+
path = libRNKeyboardEvents.a;
573+
remoteRef = D339AEEF1BAA808800CFA651 /* PBXContainerItemProxy */;
574+
sourceTree = BUILT_PRODUCTS_DIR;
575+
};
546576
D374ADC41BA929BA00453203 /* libRNKeychain.a */ = {
547577
isa = PBXReferenceProxy;
548578
fileType = archive.ar;

0 commit comments

Comments
 (0)