1. 用户详情页头部关注按钮

2. 日记详情页头部更多按钮
3. 评论删除
This commit is contained in:
xuwenyang 2019-05-24 18:56:20 +08:00
parent d021cee7a9
commit 44187ec26b
8 changed files with 223 additions and 13 deletions

View file

@ -40,7 +40,7 @@ export default class Comment extends Component {
{ {
editable editable
? <CommentActionIcon></CommentActionIcon> ? <CommentActionIcon onPress={this.props.onCommentAction}></CommentActionIcon>
: null : null
} }

View file

@ -4,13 +4,16 @@ import {
ActivityIndicator, ActivityIndicator,
StyleSheet, StyleSheet,
FlatList, FlatList,
Text, View Text,
View,
Alert
} from 'react-native'; } from 'react-native';
import {Divider} from "react-native-elements"; import {Divider} from "react-native-elements";
import Touchable from '../touchable'; import Touchable from '../touchable';
import Color from '../../style/color'; import Color from '../../style/color';
import Api from '../../util/api'; import Api from '../../util/api';
import Msg from '../../util/msg'
import Comment from './comment'; import Comment from './comment';
@ -21,6 +24,8 @@ export default class CommentList extends Component {
super(props); super(props);
this.diaryId = props.diaryId; this.diaryId = props.diaryId;
this.editable = props.editable || false;
this.state = { this.state = {
comments: [] comments: []
}; };
@ -45,6 +50,41 @@ export default class CommentList extends Component {
} }
} }
_onCommentAction(comment) {
ActionSheet.showActionSheetWithOptions({
options:['删除回复', '取消'],
cancelButtonIndex: 1,
destructiveButtonIndex: 0
}, (index) => {
if(index == 0) {
Alert.alert('提示', '确认删除回复?', [
{
text: '删除',
style: 'destructive',
onPress: () => {
Api.deleteComment(comment.id)
.then(() => {
const filterComments = this.state.comments.filter(it => it.id !== comment.id);
this.setState({
comments: filterComments
});
})
.catch(e => {
Msg.showMsg('删除失败');
})
.done();
}
},
{
text: '取消',
onPress: () => {}
}
]);
}
});
}
render() { render() {
return ( return (
<View style={localStyle.container}> <View style={localStyle.container}>
@ -59,7 +99,9 @@ export default class CommentList extends Component {
renderItem={({item}) => { renderItem={({item}) => {
return ( return (
<Touchable onPress={() => {}}> <Touchable onPress={() => {}}>
<Comment comment={item}></Comment> <Comment comment={item} editable={this.editable}
onCommentAction={() => this._onCommentAction(item)}>
</Comment>
</Touchable> </Touchable>
) )
}} }}

View file

@ -77,7 +77,7 @@ export default class DiaryBrief extends Component {
{ {
this.editable this.editable
? <DiaryActionIcon diaryId={diary.id} ? <DiaryActionIcon diaryId={diary.id}
onPress={this.props.onDeleteDiary}></DiaryActionIcon> onPress={this.props.onDiaryAction}></DiaryActionIcon>
: null : null
} }
</View> </View>

View file

@ -13,7 +13,9 @@ export default class DiaryFull extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.diary = props.diary; this.diary = props.diary;
this.editable = props.editable || false;
} }
render() { render() {
@ -54,7 +56,7 @@ export default class DiaryFull extends Component {
</View> </View>
</View> </View>
<CommentList diaryId={diary.id}></CommentList> <CommentList diaryId={diary.id} editable={this.editable}></CommentList>
</View> </View>
); );

View file

@ -81,13 +81,17 @@ export default class DiaryList extends Component {
} }
}, },
passProps: { passProps: {
diary: diary diary: diary,
user: diary.user,
editable: this.editable,
onDiaryAction: this._onDiaryAction.bind(this)
} }
} }
}); });
} }
_onDeleteDiary(diary) { _onDiaryAction(diary) {
ActionSheet.showActionSheetWithOptions({ ActionSheet.showActionSheetWithOptions({
options:['修改','删除', '取消'], options:['修改','删除', '取消'],
cancelButtonIndex: 2, cancelButtonIndex: 2,
@ -111,7 +115,8 @@ export default class DiaryList extends Component {
}) })
.catch(e => { .catch(e => {
Msg.showMsg('日记删除失败'); Msg.showMsg('日记删除失败');
}); })
.done();
}}, }},
{text: '取消', onPress: () => {}}, {text: '取消', onPress: () => {}},
]); ]);
@ -127,6 +132,7 @@ export default class DiaryList extends Component {
this.setState({refreshing: true, refreshFailed: false}); this.setState({refreshing: true, refreshFailed: false});
this.dataSource.refresh() this.dataSource.refresh()
.then(result => { .then(result => {
console.log('diary list result:', result);
if(!result) { if(!result) {
throw { throw {
message: 'refresh diary no result' message: 'refresh diary no result'
@ -202,7 +208,7 @@ export default class DiaryList extends Component {
data={this.state.diaries} data={this.state.diaries}
keyExtractor={(item, index) => { keyExtractor={(item, index) => {
return item.id.toString() return item.id.toString() + item.comment_count;
}} }}
renderItem={({item}) => { renderItem={({item}) => {
@ -213,7 +219,7 @@ export default class DiaryList extends Component {
editable={this.editable} editable={this.editable}
onUserIconPress={() => this._onUserIconPress(item)} onUserIconPress={() => this._onUserIconPress(item)}
onDeleteDiary={() => this._onDeleteDiary(item)} onDiaryAction={() => this._onDiaryAction(item)}
> >
</DiaryBrief> </DiaryBrief>

View file

@ -1,18 +1,69 @@
import React, {Component} from 'react'; import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, ScrollView} from 'react-native'; import {Platform, StyleSheet, Text, View, ScrollView} from 'react-native';
import {Navigation} from 'react-native-navigation';
import Color from '../style/color'; import Color from '../style/color';
import {Icon} from '../style/icon';
import Msg from '../util/msg';
import Api from '../util/api'
import DiaryFull from '../component/diary/diaryFull'; import DiaryFull from '../component/diary/diaryFull';
import CommentInput from '../component/comment/commentInput' import CommentInput from '../component/comment/commentInput'
export default class DiaryDetailPage extends Component { export default class DiaryDetailPage extends Component {
constructor(props) {
super(props);
Navigation.events().bindComponent(this);
this.diary = props.diary;
this.user = props.user;
this.editable = props.editable || false;
this.onDiaryAction = props.onDiaryAction || (() => {});
}
static options(passProps) {
return {
topBar: {
title: {
text: '日记详情'
},
rightButtons: [{
id: 'navButtonMore',
icon: Icon.navButtonMore,
color: Color.primary // android
}]
}
};
}
navigationButtonPressed({buttonId}) {
if(this.editable) {
this.onDiaryAction();
} else {
ActionSheet.showActionSheetWithOptions({
options: ['举报', '取消'],
cancelButtonIndex: 1,
destructiveButtonIndex: 0
}, (index) => {
if(index == 0) {
// Api.report(this.diary.user_id, this.diary.id).done();
Msg.showMsg('举报成功,感谢你的贡献 :)');
}
});
}
}
render() { render() {
return ( return (
<View style={localStyle.wrap}> <View style={localStyle.wrap}>
<ScrollView style={{flex: 1}}> <ScrollView style={{flex: 1}}>
<DiaryFull diary={this.props.diary}></DiaryFull> <DiaryFull diary={this.props.diary} editable={this.editable}></DiaryFull>
</ScrollView> </ScrollView>
<CommentInput></CommentInput> <CommentInput></CommentInput>

View file

@ -1,5 +1,5 @@
import React, {Component} from 'react'; import React, {Component} from 'react';
import {StyleSheet, Text, View, Animated, DeviceEventEmitter} from 'react-native'; import {StyleSheet, Text, View, Animated, DeviceEventEmitter, Alert} from 'react-native';
import { import {
PagerScroll, PagerScroll,
TabView, TabView,
@ -9,6 +9,7 @@ import {
import {Navigation} from 'react-native-navigation'; import {Navigation} from 'react-native-navigation';
import Api from '../util/api'; import Api from '../util/api';
import {Icon} from '../style/icon'
import Event from "../util/event"; import Event from "../util/event";
import Color from '../style/color'; import Color from '../style/color';
@ -22,6 +23,7 @@ export default class UserPage extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
Navigation.events().bindComponent(this);
this.user = props.user; this.user = props.user;
this.userId = this.user ? this.user.id : (props.userId || 0); this.userId = this.user ? this.user.id : (props.userId || 0);
@ -37,7 +39,89 @@ export default class UserPage extends Component {
}; };
} }
static options(passProps) {
return passProps.user ? {
topBar: {
title: {
text: passProps.user.name
},
rightButtons: [{
id: 'followIcon',
icon: Icon.followIcon
}]
}
} : {
topBar: {
title: {
text: '我'
},
rightButtons: [{
id: 'setting',
icon: Icon.navButtonSetting,
color: Color.primary
}]
}
}
}
navigationButtonPressed({buttonId}) {
if(buttonId == 'followIcon') {
Api.addFollow(this.userId)
.then(() => {
Navigation.mergeOptions(this.props.componentId, {
topBar: {
rightButtons: [{
id: 'navButtonFollowSelected',
icon: Icon.navButtonFollowSelected
}]
}
});
Alert.alert('已关注');
})
.catch(e => {
Alert.alert('关注失败');
}).done();
} else if(buttonId == 'navButtonFollowSelected') {
Api.deleteFollow(this.userId)
.then(() => {
Navigation.mergeOptions(this.props.componentId, {
topBar: {
rightButtons: [{
id: 'followIcon',
icon: Icon.followIcon
}]
}
});
Alert.alert('已取消关注');
})
.catch(e => {
Alert.alert('取消关注失败');
}).done();
}
}
componentDidMount(){ componentDidMount(){
if(this.userId) {
Api.getRelation(this.userId)
.then(re => {
this.followed = re;
if(this.followed) {
Navigation.mergeOptions(this.props.componentId, {
topBar: {
rightButtons: [{
id: 'navButtonFollowSelected',
icon: Icon.navButtonFollowSelected
}]
}
});
}
});
}
this.listener = DeviceEventEmitter.addListener(Event.updateNotebooks, (param) => { this.listener = DeviceEventEmitter.addListener(Event.updateNotebooks, (param) => {
this.notebookList.refresh(); this.notebookList.refresh();
}); });

View file

@ -92,6 +92,10 @@ async function getDiaryComments(diaryId) {
return call('GET', '/diaries/' + diaryId + '/comments') return call('GET', '/diaries/' + diaryId + '/comments')
} }
async function deleteComment(id) {
return call('DELETE', '/comments/' + id)
}
async function getSelfNotebooks() { async function getSelfNotebooks() {
return call('GET', '/notebooks/my') return call('GET', '/notebooks/my')
} }
@ -108,6 +112,10 @@ async function getRelationReverseUsers(page, page_size) {
return call('GET', `/relation/reverse?page=${page}&page_size=${page_size}`); return call('GET', `/relation/reverse?page=${page}&page_size=${page_size}`);
} }
async function getRelation(user_id) {
return call('GET', '/relation/' + user_id);
}
async function deleteFollow(user_id) { async function deleteFollow(user_id) {
return call('DELETE', '/relation/' + user_id); return call('DELETE', '/relation/' + user_id);
} }
@ -116,6 +124,11 @@ async function deleteFollowBy(user_id) {
return call('DELETE', '/relation/reverse/' + user_id); return call('DELETE', '/relation/reverse/' + user_id);
} }
async function addFollow(user_id) {
return call('POST', '/relation/' + user_id);
}
async function getMessagesHistory() { async function getMessagesHistory() {
return call('GET', '/tip/history'); return call('GET', '/tip/history');
} }
@ -156,6 +169,13 @@ async function deleteNotebook(id) {
return call('DELETE', '/notebooks/' + id) return call('DELETE', '/notebooks/' + id)
} }
async function report(user_id, diary_id) {
return call('POST', '/reports/', {
user_id: user_id,
diary_id: diary_id,
});
}
async function upload(method, api, body) { async function upload(method, api, body) {
let token = await TokenManager.getToken(); let token = await TokenManager.getToken();
@ -282,19 +302,24 @@ export default {
deleteDiary, deleteDiary,
getDiaryComments, getDiaryComments,
deleteComment,
getSelfNotebooks, getSelfNotebooks,
getUserNotebooks, getUserNotebooks,
getRelationUsers, getRelationUsers,
getRelationReverseUsers, getRelationReverseUsers,
getRelation,
deleteFollow, deleteFollow,
deleteFollowBy, deleteFollowBy,
addFollow,
getMessagesHistory, getMessagesHistory,
updateNotebookCover, updateNotebookCover,
createNotebook, createNotebook,
updateNotebook, updateNotebook,
deleteNotebook deleteNotebook,
report
} }