Authored by 盖剑秋

Part of post reply. reviewed by redding.

... ... @@ -15,6 +15,7 @@ import {
Easing,
Platform,
TextInput,
Alert,
} from 'react-native'
import UserBrief from '../home/UserBrief';
... ... @@ -60,6 +61,12 @@ export default class SubjectPost extends Component {
this.blurAll = this.blurAll.bind(this);
this.renderToolContainer = this.renderToolContainer.bind(this);
this.someOneToReply = '';
this.replyToSomeOneElse = this.replyToSomeOneElse.bind(this);
this.commentId = '';
this.cidTo = '';
this.replyContent='';
this.commitComment = this.commitComment.bind(this);
}
componentDidMount(){
... ... @@ -163,6 +170,8 @@ export default class SubjectPost extends Component {
style={styles.lzContainer}
onPress={
()=>{
this.cidTo = this.props.authorUid;
this.commentId = '';
this.setState({replyState: this.currentReplyState})
}
}
... ... @@ -196,8 +205,13 @@ export default class SubjectPost extends Component {
autoCapitalize={'none'}
autoCorrect={false}
autoFocus={true}
onChangeText={
(text)=>{
this.replyContent = text;
}
}
/>
<Text style={styles.submitText}>发送</Text>
<Text style={styles.submitText} onPress={this.commitComment}>发送</Text>
</View>
</View>
);
... ... @@ -206,19 +220,30 @@ export default class SubjectPost extends Component {
case ReplyState.replySomeone: {
return (
<View style={styles.toolContainer}>
<TouchableOpacity style={styles.imgIcon} onPress={this.showImagePannel}>
<Image source={require('../../images/pic1.png')}/>
<Image style={styles.imgIcon} source={iconSouce}/>
<TouchableOpacity style={styles.imgButton} onPress={this.showImagePannel}>
</TouchableOpacity>
<TouchableOpacity style={styles.keyboardIcon} onPress={this.blurAll}>
<Image style={styles.keyboardIcon} source={require('../../images/jianpan1.png')} />
<Image source={require('../../images/jianpan1.png')} />
</TouchableOpacity>
<View style={styles.rightContainer}>
<Text
style={styles.boardText}
onPress={this.showBoardPannel}
>
{this.props.selectedBoard}
</Text>
<View style={[styles.rightContainer]}>
<TextInput
ref='textInput'
style={styles.replyTextInput}
placeholderTextColor='#b0b0b0'
placeholder={'回复'+this.someOneToReply+':'}
multiline={true}
autoCapitalize={'none'}
autoCorrect={false}
autoFocus={true}
onChangeText={
(text)=>{
this.replyContent = text;
}
}
/>
<Text style={styles.submitText} onPress={this.commitComment}>发送</Text>
</View>
</View>
);
... ... @@ -229,6 +254,22 @@ export default class SubjectPost extends Component {
}
}
commitComment() {
if (this.replyContent.length == 0) {
Alert.alert('抱歉','请先输入内容');
return;
}
let params = {
postId: this.props.postId,
commentId: this.commentId,
cidFrom: this.props.cidFrom,
cidTo: this.cidTo,
authorUid: this.props.authorUid,
content: this.replyContent,
}
this.props.commentWithParams(params);
this.blurAll();
}
renderRow(rowData, sectionId) {
switch (sectionId) {
case 'header':
... ... @@ -279,7 +320,7 @@ export default class SubjectPost extends Component {
style={styles.commentContainer}
onPress={
()=> {
this.replySomeone(rowData.nickName);
this.replyToSomeOneElse(rowData.nickName);
}
}
>
... ... @@ -290,6 +331,8 @@ export default class SubjectPost extends Component {
timeago={rowData.timeago}
isOwner={rowData.LZ}
onPressAvatar={() => {
this.cidTo = rowData.cidTo;
this.commentId = rowData.commentId;
this.props.onPressAvatar && this.props.onPressAvatar();
}}
/>
... ... @@ -304,8 +347,10 @@ export default class SubjectPost extends Component {
}
}
replyToSomeOne(someOne) {
replyToSomeOneElse(someOne) {
this.someOneToReply = someOne;
this.currentReplyState = ReplyState.replySomeone;
this.setState({replyState: this.currentReplyState});
}
renderLikeAvatar(avatars) {
... ... @@ -328,6 +373,7 @@ const styles = StyleSheet.create({
container: {
top: 0,
flex: 1,
backgroundColor: 'white',
},
likePannel: {
backgroundColor: 'white',
... ...
... ... @@ -132,4 +132,9 @@ export default keyMirror({
LIKE_MESSAGE_REQUEST: null,
LIKE_MESSAGE_SUCCESS: null,
LIKE_MESSAGE_FAILURE: null,
SUBJECT_REPLY_REQUEST: null,
SUBJECT_REPLY_SUCCESS: null,
SUBJECT_REPLY_FAILURE: null,
SUBJECT_REPLY_UPDATE: null,
});
... ...
... ... @@ -58,6 +58,7 @@ class SubjectPostContainer extends Component {
super(props);
this.onEndReached = this.onEndReached.bind(this);
this.assetsSelected = this.assetsSelected.bind(this);
this.commentWithParams = this.commentWithParams.bind(this);
}
componentDidMount() {
... ... @@ -87,6 +88,10 @@ class SubjectPostContainer extends Component {
this.props.actions.assetsSelected(assets);
}
commentWithParams(params) {
this.props.actions.commentWithParams(params);
}
render() {
let {headIcon,nickName} = this.props.subject.authorInfo;
let timeagoStr = timeago().format(this.props.subject.createTime, 'zh_CN');
... ... @@ -105,26 +110,26 @@ class SubjectPostContainer extends Component {
let dataBlob = {
header : [header],
// 'title': [this.props.subject.postsTitle],
title: ['港南都爱啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦'],
// content: [this.props.subject.blocks.toJS()],
content: [[
{
"contentData": "前几天这条关于adidas Originals NMD入手攻略的资讯发布后,评论区的童鞋们都“炸”啦,各种关于如何排队如何购买的问题一股脑地涌来。为了让大家能顺利买到NMD,今天小编就扮演一下临时客服,帮大家解决几个困惑。",
"order": 1,
"templateKey": "text"
},
{
"contentData": "http://img11.static.yhbimg.com/yhb-img01/2016/03/11/07/017c954c712e3e732f565d56d193c761af.jpg?imageView/2/w/640/h/640",
"order": 2,
"templateKey": "image"
},
{
"contentData": "http://img11.static.yhbimg.com/yhb-img01/2016/03/11/07/012868bed62e639554e5fecb09b6d44cfe.jpg?imageView/2/w/640/h/640",
"order": 3,
"templateKey": "image"
}
],],
'title': [this.props.subject.postsTitle],
// title: ['港南都爱啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦'],
content: [this.props.subject.blocks.toJS()],
// content: [[
// {
// "contentData": "前几天这条关于adidas Originals NMD入手攻略的资讯发布后,评论区的童鞋们都“炸”啦,各种关于如何排队如何购买的问题一股脑地涌来。为了让大家能顺利买到NMD,今天小编就扮演一下临时客服,帮大家解决几个困惑。",
// "order": 1,
// "templateKey": "text"
// },
// {
// "contentData": "http://img11.static.yhbimg.com/yhb-img01/2016/03/11/07/017c954c712e3e732f565d56d193c761af.jpg?imageView/2/w/640/h/640",
// "order": 2,
// "templateKey": "image"
// },
// {
// "contentData": "http://img11.static.yhbimg.com/yhb-img01/2016/03/11/07/012868bed62e639554e5fecb09b6d44cfe.jpg?imageView/2/w/640/h/640",
// "order": 3,
// "templateKey": "image"
// }
// ],],
like: [likeData],
comments: this.props.subject.commentList.toJS(),
... ... @@ -139,6 +144,10 @@ class SubjectPostContainer extends Component {
assetsSelected={this.assetsSelected}
assets={this.props.subject.assets.toJS()}
commentCount={this.props.subject.commentCount}
commentWithParams={this.commentWithParams}
postId={this.props.subject.id}
cidFrom={this.props.user.profile.uid}
authorUid={this.props.subject.authorInfo.uid}
/>
</View>
);
... ...
... ... @@ -11,6 +11,7 @@ import PostingService from '../../services/PostingService';
import Immutable, {List, Record} from 'immutable';
import {
NativeModules,
Alert,
} from 'react-native'
let YH_CommunityAssetsPicker = NativeModules.YH_CommunityAssetsPicker;
... ... @@ -187,8 +188,10 @@ export function updateUploadState(url,fileName) {
if (posting.postPercent == 1) {
let assets = posting.assets.toJS();
let imageStr = '';
let sizeStr = '';
for (let i = 0; i < assets.length; i++) {
imageStr += assets[i].webURL+',';
sizeStr += assets[i].width + 'x' + assets[i].height +',';
}
let param = {
postTitle: encodeURI(posting.title),
... ... @@ -196,6 +199,7 @@ export function updateUploadState(url,fileName) {
forumCode: posting.currentBoardId,
contentData: encodeURI(posting.content),
images: imageStr,
sizes: sizeStr,
}
return new PostingService().commitPost(param).then((json) => {
store.delete(POSTING_CACHE_KEY);
... ...
... ... @@ -22,6 +22,10 @@ const {
SUBJECT_COMMENTS_SUCCESS,
SUBJECT_COMMENTS_FAILURE,
SUBJECT_ASSETS_SELECTED,
SUBJECT_REPLY_REQUEST,
SUBJECT_REPLY_SUCCESS,
SUBJECT_REPLY_FAILURE,
SUBJECT_REPLY_UPDATE,
} = require('../../constants/actionTypes').default;
export function requestPostContent(postsId) {
... ... @@ -97,24 +101,26 @@ export function commentsRequestSuccess(json) {
let {list} = json;
let newList = [];
list && list.map((obj,i)=> {
let {createTime, reply, replyTo, blocks} = obj;
let {createTime, reply, replyTo, blocks,postInfo,id} = obj;
let timeagoStr = timeago().format(createTime, 'zh_CN');
let newBlocks = [];
blocks && blocks.map((blockItem, i) => {
let {commentId,content,templateKey,orderBy} = blockItem;
let newItem = {
"contentData": content,
"order": orderBy,
"templateKey": templateKey,
"contentData": content||'',
"order": orderBy||'',
"templateKey": templateKey||'',
};
newBlocks.push(newItem);
})
let newObj={
timeago: timeagoStr,
headIcon: reply.headIcon,
nickName: reply.nickName,
commentId: id||'',
cidTo: postInfo.authorUid||'',
timeago: timeagoStr||'',
headIcon: reply.headIcon||'',
nickName: reply.nickName||'',
LZ:false,
blocks: newBlocks,
blocks: newBlocks||[],
}
newList.push(newObj);
})
... ... @@ -139,3 +145,90 @@ export function assetsSelected(assets) {
payload: assets,
}
}
export function commentWithParams(params) {
return (dispatch, getState) => {
dispatch(startComment());
let {subject} = getState();
let assets = subject.assets.toJS();
if (assets.length) {
for (let i = 0; i < assets.length; i++) {
let asset = assets[i]
new PostingService().uploadImageAsset(asset)
.then(response => {
dispatch(updateCommentProgress(response, params));
}).catch(error => {
dispatch(commentFail(error));
});
}
} else {
dispatch(commitComment(params));
}
}
}
export function startComment() {
return {
type: SUBJECT_REPLY_REQUEST,
}
}
export function commitComment(params) {
return dispatch => {
new PostingService().commitReply(params)
.then(response => {
dispatch(commentSuccess(response));
}).catch(error => {
dispatch(commentFail(error));
});
}
}
export function updateCommentProgress(url, params) {
return (dispatch, getState) => {
let {subject} = getState();
let {assetsUrlStr, assetFinishCount} = subject;
let newStr = assetsUrlStr + url + ',';
let newCount = assetFinishCount + 1;
let payloadData = {
newStr,
newCount,
};
console.log(payloadData);
dispatch(commentImageStateChanged(payloadData));
dispatch(() => {
let {subject} = getState();
if (subject.assetFinishCount == subject.assets.toJS().length) {
let newParams = {
...params,
images: subject.assetsUrlStr,
}
console.log(newParams);
dispatch(commitComment(newParams));
}
});
}
}
export function commentImageStateChanged(payloadData) {
return {
type: SUBJECT_REPLY_UPDATE,
payload: payloadData,
}
}
export function commentSuccess(json) {
return {
type: SUBJECT_REPLY_SUCCESS,
payload: json,
}
}
export function commentFail (error) {
return {
type: SUBJECT_COMMENTS_FAILURE,
payload: error,
}
}
... ...
... ... @@ -50,6 +50,10 @@ let InitialState = Record({
commentList: List(),//
assets: List(),//回复里面的图片。
assetsUrlStr: '',
assetFinishCount: 0,
isReplying: false,
replyError: null,
});
export default InitialState;
... ...
... ... @@ -23,6 +23,11 @@ const {
SUBJECT_COMMENTS_SUCCESS,
SUBJECT_COMMENTS_FAILURE,
SUBJECT_ASSETS_SELECTED,
SUBJECT_REPLY_REQUEST,
SUBJECT_REPLY_SUCCESS,
SUBJECT_REPLY_FAILURE,
SUBJECT_REPLY_UPDATE,
} = require('../../constants/actionTypes').default;
const initialState = new InitialState;
... ... @@ -132,6 +137,32 @@ export default function postingReducer(state = initialState, action) {
return nextState;
}
break;
case SUBJECT_REPLY_REQUEST: {
let nextState = state.set('isReplying',true).set('replyError',null);
return nextState;
}
break;
case SUBJECT_REPLY_SUCCESS:{
let nextState = state.set('assets',Immutable.fromJS([]))
.set('assetsUrlStr','')
.set('assetFinishCount',0)
.set('isReplying',false)
.set('replyError',error)
return nextState;
}
break;
case SUBJECT_REPLY_FAILURE: {
let nextState = state.set('isReplying',false).set('replyError',action.payload);
return nextState;
}
break;
case SUBJECT_REPLY_UPDATE: {
let {newStr,newCount} = action.payload;
let nextState = state.set('assetsUrlStr',newStr).set('assetFinishCount',newCount);
return nextState;
}
break;
default:
return initialState;
break;
... ...
... ... @@ -433,14 +433,8 @@ export function uploadAvatar(assetURL) {
// dispatch(startUploadAvatar());
let {user} = getState();
let formData = new FormData()
let params = {
'fileData': {
name: 'avatar.jpg',
type: 'image/jpeg',
uri: assetURL.url,
},
assetURL,
uid: user.profile.uid,
bucket: 'yhb_head',
};
... ... @@ -451,6 +445,7 @@ export function uploadAvatar(assetURL) {
dispatch(avatarUploadSuccess(json));
dispatch(syncUserWithSSOUid(user.profile.uid));
}).catch(error => {
console.log(error);
dispatch(avatarUploadFailure(error));
})
... ... @@ -687,7 +682,6 @@ function parseJson(json) {
}
function parseReply(json) {
console.log('========>', json);
let {lastedTime, list} = json;
let replies = [];
list && list.map((item, i) => {
... ...
... ... @@ -42,6 +42,19 @@ export default class PostingService {
});
}
async commitReply(params) {
return await this.api.get({
url:'',
body: {
method:'app.social.addComment',
...params,
}
}).then((json) => {
return json;
}).catch((error) => {
throw(error);
});
}
async getBoardList() {
... ... @@ -114,7 +127,8 @@ export default class PostingService {
options.body = formData;
options.method = 'post';
options.headers = {'project':'social',HTTP_REFERER:'admin.yohobuy.com'};
console.log('zhixingdao zheli le ..............SSSSSSSSSSSSSSSSSSSSSSSS');
console.log(options);
return await fetch('http://upload.static.yohobuy.com', options)
.then((response) => {
... ...
... ... @@ -3,22 +3,74 @@
import Request from '../../common/services/Request';
import moment from 'moment';
import {Platform, Dimensions, NativeModules, CameraRoll,} from 'react-native';
import DeviceInfo from 'react-native-device-info';
import queryString from 'query-string';
import RNNativeConfig from '../../common/services/RNNativeConfig';
export default class UserService {
constructor() {
this.api = new Request();
}
async updateUserAvatar(params) {
return await this.api.get({
url: '',
body: {
method:'app.social.modifyHead',
...params,
// return await this.api.post({
// url: '',
// body: {
// method:'app.social.modifyHead',
// ...params,
// }
// }).then((json)=> {
// return json;
// }).catch((error) => {
// throw error;
// });
let {assetURL,uid,bucket}= params
let formData = new FormData();
formData.append('fileData',{name:'avatar.jpg',type: 'image/jpeg','uri':assetURL});
let app_version = DeviceInfo.getBuildNumber();
let os_version = DeviceInfo.getSystemVersion();
let client_type = Platform.OS === 'ios' ? 'iphone' : 'android';
let {height, width} = Dimensions.get('window');
let screen_size = width + 'x' + height;
let privateKey = RNNativeConfig.getPrivateKey();
formData.append('app_version',app_version);
formData.append('os_version',os_version);
formData.append('client_type',client_type);
formData.append('screen_size',width + 'x' + height);
formData.append('privateKey',privateKey);
formData.append('uid',uid);
formData.append('bucket',bucket);
formData.append('method','app.social.modifyHead');
formData.append('client_secret','aaaaaaaaaaaaaaaaaaaaa')
let options = {};
options.body = formData;
options.method = 'post';
options.headers = {method:'app.social.modifyHead',HTTP_REFERER:'admin.yohobuy.com',client_secret:'aaaaaaaaaaaaaaaaaaaaa'};
return await fetch('http://192.168.102.206:8095/social', options)
.then((response) => {
return response.json().then(
(json) => {
console.log(json);
if (json.code == 200) {
return json.data.imagesList[0];
}else {
throw(json);
}
}).then((json)=> {
return json;
}
)
}).catch((error) => {
throw error;
console.log('wwwwwwwwwwwwwwww');
console.log(error);
throw(error);
});
}
... ...