Authored by 盖剑秋

Delete post and report post. reviewed by redding.

... ... @@ -74,6 +74,10 @@ import {
modifyUserInfo,
} from './reducers/user/userActions';
import {
onRightPressed
} from './reducers/subject/subjectPostActions';
import PostingService from './services/PostingService';
/**
... ... @@ -279,6 +283,9 @@ export default function community(platform) {
hideNavBar={false}
component={SubjectPostContainer}
initial={false}
onBack={this.onBack}
rightButtonImage={require('./images/posting/share.png')}
onRight={this.subjectPostOnRight}
/>
<Scene
... ... @@ -393,6 +400,9 @@ export default function community(platform) {
Actions.pop();
},
subjectPostOnRight(state) {
state.dispatch(onRightPressed());
},
/*
* 自定义导航push动画
*
... ...
... ... @@ -54,7 +54,7 @@ export default class SPLikeCell extends React.Component {
render() {
let {users, like, browse} = this.props;
let likeTextMarginLeft = users.length > 0 ? -10 : 0;
let likeTextMarginLeft = users.length > 1 ? -10*(users.length -1) : 0;
return (
<TouchableOpacity onPress={() => {
this.props.onPressLikeCell && this.props.onPressLikeCell()
... ... @@ -82,8 +82,9 @@ let styles = StyleSheet.create({
container: {
backgroundColor: 'white',
height: 50,
marginLeft: 15,
marginRight: 15,
borderColor: '#a0a0a0',
borderTopWidth: 0.5,
borderBottomWidth: 0.5,
flexDirection: 'row',
justifyContent: 'space-between',
flex: 1,
... ... @@ -108,6 +109,7 @@ let styles = StyleSheet.create({
flex: 1,
flexDirection: 'row',
alignItems: 'center',
left: 15,
},
avatarPannel: {
flexDirection: 'row-reverse',
... ... @@ -118,6 +120,7 @@ let styles = StyleSheet.create({
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-end',
right: 15,
},
likeAvatar: {
width: 30,
... ...
... ... @@ -23,9 +23,20 @@ export default class SubjectContent extends Component {
{this.props.blocks.map((item,i) => {
let content = item.contentData||'';
if (item.templateKey === 'text') {
return(
<Text key={i} style={styles.contentText}>{decodeURI(content)}</Text>
)
if (this.props.replyTo&&this.props.replyTo.nickName&&this.props.replyTo.nickName.length&&this.props.replyTo.uid) {
return(
<Text key={i} style={styles.contentText}>
<Text>回复</Text>
<Text style={{color:'#4a90e2'}} onPress={()=>{this.props.onPressAvatar(this.props.replyTo.uid);}}>{this.props.replyTo.nickName}</Text>
<Text>':'+{decodeURI(content)}</Text>
</Text>
)
}else {
return(
<Text key={i} style={styles.contentText}>{decodeURI(content)}</Text>
)
}
} else if (item.templateKey === 'image') {
let imgWidth = this.props.contentWidth||width-30;
let imgHeight = imgWidth;
... ... @@ -58,7 +69,7 @@ const styles = StyleSheet.create({
lineHeight: 24,
},
contentImage: {
backgroundColor:'green',
backgroundColor:'#a0a0a0',
resizeMode: 'stretch',
width:320,
height: 320,
... ...
... ... @@ -165,10 +165,15 @@ export default class SubjectPost extends Component {
switch (this.state.replyState) {
case ReplyState.replyNone: {
if (this.props.likeState == 'Y') {
iconSouce=require('../../images/home/like.png');
} else if (this.props.likeState == 'N'){
iconSouce=require('../../images/home/unlike.png');
}
return (
<View style={styles.toolContainer}>
<SlicedImage style={styles.imgIcon} source={iconSouce}/>
<TouchableOpacity style={styles.imgButton} onPress={this.showImagePannel}>
<TouchableOpacity style={styles.imgButton} onPress={this.props.onPressLikeOrDislike}>
</TouchableOpacity>
<View style={styles.rightContainer}>
<TouchableOpacity
... ... @@ -307,7 +312,7 @@ export default class SubjectPost extends Component {
break;
case 'shareGoods':
return (
<TouchableOpacity>
<TouchableOpacity onPress={this.props.onPressShareGoods}>
<View style={styles.shareGoodsContainer}>
<SlicedImage style={styles.shareGoodsImage} source={{uri:rowData.productUrl}}/>
<View style={styles.shareGoodsRightPannel}>
... ... @@ -331,6 +336,8 @@ export default class SubjectPost extends Component {
);
break;
case 'comments':
console.log('.............');
console.log(rowData);
return (
<TouchableOpacity
style={styles.commentContainer}
... ... @@ -352,7 +359,7 @@ export default class SubjectPost extends Component {
this.props.onPressAvatar && this.props.onPressAvatar();
}}
/>
<SubjectContent contentWidth={width-65} left={20} blocks={rowData.blocks}/>
<SubjectContent contentWidth={width-65} left={20} blocks={rowData.blocks} replyTo={rowData.replyTo} onPressAvatar={this.props.onPressAvatar}/>
<View style={styles.commentSeparator}/>
</View>
</TouchableOpacity>
... ...
... ... @@ -137,6 +137,11 @@ export default keyMirror({
SUBJECT_REPLY_SUCCESS: null,
SUBJECT_REPLY_FAILURE: null,
SUBJECT_REPLY_UPDATE: null,
SUBJECT_DO_NOTHING: null,
SUBJECT_LIKE_SUCCESS: null,
SUBJECT_UNLIKE_SUCCESS: null,
SUBJECT_LIKE_REQUEST: null,
SUBJECT_UNLIKE_REQUEST: null,
LIKE_LIST_REQUEST: null, // 帖子详情页点赞列表
LIKE_LIST_SUCCESS: null,
... ...
... ... @@ -95,8 +95,6 @@ class PostingContainer extends Component{
}
Actions.refresh({key: 'Posting', rightButtonTextStyle: {color:'white'}});
}
// let sendBtnColor = nextProps.posting.dataValid?'white':'#a0a0a0';
// Actions.refresh({key: 'Posting', rightButtonTextStyle: {color:sendBtnColor}});
}
boardSelectedWithName(boardName,boardCode) {
... ...
... ... @@ -64,6 +64,8 @@ class SubjectPostContainer extends Component {
this.onPressSection = this.onPressSection.bind(this);
this.onPressReportOrDelete = this.onPressReportOrDelete.bind(this);
this.onPressLikeCell = this.onPressLikeCell.bind(this);
this.onPressLikeOrDislike = this.onPressLikeOrDislike.bind(this);
this.onPressShareGoods = this.onPressShareGoods.bind(this);
}
componentDidMount() {
... ... @@ -92,6 +94,12 @@ class SubjectPostContainer extends Component {
this.props.actions.commentWithParams(params);
}
onPressShareGoods() {
let params = {
productSkn: this.props.subject.shareProductSkn,
};
NativeModules.YH_CommunityHelper.displayProductDetail(params);
}
onPressAvatar(uid) {
this.props.actions.goToUserOrMe(uid);
}
... ... @@ -101,7 +109,27 @@ class SubjectPostContainer extends Component {
}
onPressReportOrDelete() {
console.log('onPressReportOrDelete');
if (this.props.subject.LZ) {
this.props.actions.doDelete(this.props.subject.id);
} else {
let params = {
postsId: this.props.subject.id,
loginUid: this.props.user.profile.uid,
contentData: '涉黄',
}
this.props.actions.doReport(params);
}
}
onPressLikeOrDislike() {
if (this.props.subject.inLikeAction) {
return;
}
if (this.props.subject.hasPraise == 'Y') {
this.props.actions.subjectUnlike(this.props.subject.id);
}else if(this.props.subject.hasPraise == 'N'){
this.props.actions.subjectLike(this.props.subject.id);
}
}
onPressLikeCell(postId, likeCount) {
... ... @@ -157,6 +185,9 @@ class SubjectPostContainer extends Component {
onPressSection={this.onPressSection}
onPressReportOrDelete={this.onPressReportOrDelete}
onPressLikeCell={this.onPressLikeCell}
onPressLikeOrDislike={this.onPressLikeOrDislike}
likeState={this.props.subject.hasPraise}
onPressShareGoods={this.onPressShareGoods}
/>
</View>
);
... ...
... ... @@ -10,8 +10,11 @@ import PostingService from '../../services/PostingService';
import Immutable, {List, Record} from 'immutable';
import {
NativeModules,
ActionSheetIOS,
Alert,
} from 'react-native';
import timeago from 'timeago.js';
import HomeService from '../../services/HomeService';
const {
SUBJECT_CONTENT_REQUEST,
... ... @@ -28,6 +31,11 @@ const {
SUBJECT_REPLY_UPDATE,
GO_TO_LIKE_LIST,
SUBJECT_DO_NOTHING,
SUBJECT_LIKE_SUCCESS,
SUBJECT_UNLIKE_SUCCESS,
SUBJECT_LIKE_REQUEST,
SUBJECT_UNLIKE_REQUEST,
} = require('../../constants/actionTypes').default;
export function goToLikeList(postId, likeCount) {
... ... @@ -38,6 +46,168 @@ export function goToLikeList(postId, likeCount) {
};
}
export function subjectLikeRequest(json) {
return {
type: SUBJECT_LIKE_REQUEST,
payload: json
};
}
export function subjectLike(postId) {
return (dispatch, getState) => {
dispatch(subjectLikeRequest(postId));
let {user} = getState();
return new HomeService().postLike(postId, user.profile.uid)
.then(json => {
dispatch({
type: SUBJECT_LIKE_SUCCESS
})
__DEV__ && console.log(json);
})
.catch(error => {
__DEV__ && console.log(error);
});
};
}
export function subjectUnlikeRequest(json) {
return {
type: SUBJECT_UNLIKE_REQUEST,
payload: json
};
}
export function subjectUnlike(postId) {
return (dispatch, getState) => {
dispatch(subjectUnlikeRequest(postId));
let {user} = getState();
return new HomeService().postUnlike(postId, user.profile.uid)
.then(json => {
dispatch({
type: UBJECT_UNLIKE_SUCCESS
})
__DEV__ && console.log(json);
})
.catch(error => {
__DEV__ && console.log(error);
});
};
}
export function onRightPressed() {
return (dispatch, getState) => {
dispatch(onRight());
let {subject} = getState();
if (subject.LZ && !subject.revieweState) {
const BUTTONS = ['删除','取消'];
ActionSheetIOS.showActionSheetWithOptions({
options: BUTTONS,
cancelButtonIndex: 1,
},
(buttonIndex) => {
if (buttonIndex == 0) {
dispatch(doDelete(subject.id));
}
});
} else {
let params = {
postsId: subject.id,
appType: 1,
}
new PostingService().getShareUrl(params).then(json => {
let {subject} = getState();
let blockAry = subject.blocks.toJS();
let content = '';
for (var i = 0; i < blockAry.length; i++) {
if (blockAry[i].templateKey == 'text') {
content = blockAry[i].contentData||'';
break;
}
}
let picUrl = '';
for (var i = 0; i < blockAry.length; i++) {
if (blockAry[i].templateKey == 'image') {
picUrl = blockAry[i].contentData||'';
break;
}
}
let newSrc = picUrl;
if (picUrl.length) {
if (picUrl.indexOf('imageView') === -1) {
newSrc = picUrl + '?imageView2/' + '1' + '/w/' + '320' + '/h/' + '320';
} else {
newSrc = picUrl.replace('{mode}', '1')
.replace('{width}', '320')
.replace('{height}', '320');
}
}
let shareInfo = {
title: subject.postsTitle||'',
content,
'picUrl':newSrc,
linkUrl: json.shareUrl,
}
console.log(shareInfo);
dispatch(doShare(shareInfo));
}).catch(error => {
console.log(error);
Alert.alert('提示','获取分享信息失败');
})
}
}
}
export function onRight() {
return {
type:'SUBJECT_DO_NOTHING'
}
}
export function doShare(shareInfo) {
console.log(shareInfo);
NativeModules.YH_CommunityHelper.showShare(shareInfo);
return {
type:'SUBJECT_DO_NOTHING'
}
}
export function doDelete(postsId) {
Alert.alert('提示','是否确认删除?',
[{text:'否'},
{text:'是', onPress: ()=>{
Actions.pop();
new PostingService().deletePost(postsId).then(json => {
Alert.alert('提示','删除成功');
console.log('......del success ....... ' + json);
}).catch(error => {
Alert.alert('提示','删除失败');
console.log('....error.......... ' +error);
})
}}]);
console.log('deleted.............');
return {
type:'SUBJECT_DO_NOTHING'
}
}
export function doReport(params) {
new PostingService().reportPost(params).then(json => {
Alert.alert('提示','举报成功');
}).catch(error => {
Alert.alert('提示','举报失败');
});
return {
type:'SUBJECT_DO_NOTHING'
}
}
export function requestPostContent(postsId) {
return dispatch => {
dispatch(doRequestContent());
... ... @@ -47,6 +217,11 @@ export function requestPostContent(postsId) {
NativeModules.YH_CommunityHelper.uid()
.then(uid => {
json.LZ = (uid == json.authorInfo.uid);
let rightImg = require('../../images/posting/share.png');
if (json.LZ&&!json.revieweState) {
rightImg = require('../../images/posting/more.png');
}
Actions.refresh({key: 'SubjectPost', rightButtonImage:rightImg});
dispatch(contentRequestSuccess(json));
})
.catch(error => {
... ... @@ -121,6 +296,10 @@ export function commentsRequestSuccess(json) {
};
newBlocks.push(newItem);
})
if (replyTo) {
let nickName = replyTo.nickName||'';
replyTo.nickName = nickName;
}
let newObj={
commentId: id||'',
cidTo: postInfo.authorUid||'',
... ... @@ -129,6 +308,7 @@ export function commentsRequestSuccess(json) {
nickName: reply.nickName||'',
LZ:false,
blocks: newBlocks||[],
replyTo,
}
newList.push(newObj);
})
... ...
... ... @@ -33,6 +33,8 @@ let InitialState = Record({
isIndexTop: false,
postsTitle: '',
praise: 0,
hasPraise:'N',
revieweState: 0,
praiseUsers: List(),//headIcon nickName uid
shareGoods: new(Record({
productName: '',
... ... @@ -54,6 +56,8 @@ let InitialState = Record({
assetFinishCount: 0,
isReplying: false,
replyError: null,
inLikeAction: false,
});
export default InitialState;
... ...
... ... @@ -28,6 +28,13 @@ const {
SUBJECT_REPLY_SUCCESS,
SUBJECT_REPLY_FAILURE,
SUBJECT_REPLY_UPDATE,
SUBJECT_DO_NOTHING,
GO_TO_LIKE_LIST,
SUBJECT_LIKE_SUCCESS,
SUBJECT_UNLIKE_SUCCESS,
SUBJECT_LIKE_REQUEST,
SUBJECT_UNLIKE_REQUEST,
} = require('../../constants/actionTypes').default;
const initialState = new InitialState;
... ... @@ -69,6 +76,8 @@ export default function postingReducer(state = initialState, action) {
shareGoods,
publishTimeString,
shareProductSkn,
revieweState,
hasPraise,
LZ,
} = action.payload;
let nextState = state.setIn(['authorInfo','headIcon'],authorInfo.headIcon||'')
... ... @@ -90,7 +99,10 @@ export default function postingReducer(state = initialState, action) {
.set('publishTimeString',publishTimeString)
.set('shareProductSkn',shareProductSkn)
.set('LZ',LZ)
.set('isContentFetching', false).set('contentError', null);
.set('isContentFetching', false)
.set('contentError', null)
.set('revieweState',revieweState)
.set('hasPraise',hasPraise||'N');
if (shareGoods) {
nextState.setIn(['shareGoods','productName'],shareGoods.productName||'')
.setIn(['shareGoods','productUrl'],shareGoods.productUrl||'')
... ... @@ -161,7 +173,19 @@ export default function postingReducer(state = initialState, action) {
let nextState = state.set('assetsUrlStr',newStr).set('assetFinishCount',newCount);
return nextState;
}
case SUBJECT_LIKE_REQUEST: {
return state.set('hasPraise','Y');
}
case SUBJECT_UNLIKE_REQUEST: {
return state.set('hasPraise','N');;
}
break;
case SUBJECT_DO_NOTHING:
return state;
break;
case GO_TO_LIKE_LIST:
return state;
break;
default:
return initialState;
... ...
... ... @@ -14,6 +14,48 @@ export default class PostingService {
this.api = new Request();
}
async getShareUrl(params) {
return await this.api.get({
url:'',
body: {
method:'app.social.getShareUrl',
...params,
}
}).then((json) => {
return json;
}).catch((error) => {
throw(error);
});
}
async reportPost(params) {
return await this.api.get({
url:'',
body: {
method:'app.social.reportPost',
...params,
}
}).then((json) => {
return json;
}).catch((error) => {
throw(error);
});
}
async deletePost(postsId) {
return await this.api.get({
url:'',
body: {
method:'app.social.delPost',
postsId
}
}).then((json) => {
return json;
}).catch((error) => {
throw(error);
});
}
async getPostContent(params) {
return await this.api.get({
url:'',
... ...