mirror of
https://github.com/timepill/timepill-app.git
synced 2025-04-30 09:59:31 +08:00
关注,取消关注,屏蔽
This commit is contained in:
parent
d169cf348a
commit
83e5b55072
13 changed files with 400 additions and 116 deletions
131
src/component/block/blockUserList.js
Normal file
131
src/component/block/blockUserList.js
Normal file
|
@ -0,0 +1,131 @@
|
|||
import React, {Component} from 'react';
|
||||
import {StyleSheet, Text, View, InteractionManager, FlatList, Alert} from 'react-native';
|
||||
import {Navigation} from 'react-native-navigation';
|
||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||
|
||||
import Touchable from '../touchable';
|
||||
import Color from '../../style/color';
|
||||
import Api from '../../util/api';
|
||||
|
||||
import UserIcon from '../userIcon';
|
||||
import Loading from '../loading';
|
||||
import {ListFooterEnd} from '../listFooter';
|
||||
|
||||
|
||||
export default class BlockUserList extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
users: [],
|
||||
isLoading: true
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
this.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
_onDeletePress(user) {
|
||||
Alert.alert('提示', '确定解除屏蔽?', [
|
||||
{text: '确定', style: 'destructive', onPress: () => {
|
||||
Api.deleteUserBlock(user.id)
|
||||
.then(() => {
|
||||
let filterUsers = this.state.users.filter((it) => it.id !== user.id);
|
||||
this.setState({
|
||||
users: filterUsers
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
Alert.alert('解除屏蔽失败');
|
||||
});
|
||||
}},
|
||||
{text: '取消', onPress: () => {}}
|
||||
]);
|
||||
}
|
||||
|
||||
refresh() {
|
||||
Api.getBlockUsers()
|
||||
.then(data => {
|
||||
if (data) {
|
||||
this.setState({
|
||||
users: data.users || [],
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
console.log('block user error:', e);
|
||||
})
|
||||
.finally(() => {
|
||||
this.setState({
|
||||
isLoading: false
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.isLoading) {
|
||||
return <Loading visible={this.state.isLoading}></Loading>;
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={localStyle.container}>
|
||||
<FlatList style={localStyle.list}
|
||||
|
||||
data={this.state.users}
|
||||
|
||||
keyExtractor={(item, index) => {
|
||||
return item.id ? item.id.toString() : index;
|
||||
}}
|
||||
|
||||
renderItem={({item}) => {
|
||||
return (
|
||||
<Touchable key={item.id} onPress={() => {}}>
|
||||
<View style={localStyle.box}>
|
||||
<UserIcon iconUrl={item.iconUrl} onPress={() => {}}></UserIcon>
|
||||
<Text style={localStyle.userName}>{item.name}</Text>
|
||||
<Touchable onPress={() => this._onDeletePress(item)}>
|
||||
<Ionicons name="md-close" size={20}
|
||||
style={localStyle.removeIcon}
|
||||
color={Color.inactiveText}
|
||||
/>
|
||||
</Touchable>
|
||||
</View>
|
||||
</Touchable>
|
||||
);
|
||||
}}
|
||||
|
||||
ListFooterComponent={() => <ListFooterEnd></ListFooterEnd>}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const localStyle = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1
|
||||
},
|
||||
list: {
|
||||
height: '100%'
|
||||
},
|
||||
box: {
|
||||
flexDirection: 'row',
|
||||
borderBottomWidth: 1,
|
||||
borderColor: Color.line,
|
||||
alignItems: 'center',
|
||||
backgroundColor: 'white',
|
||||
paddingLeft: 25
|
||||
},
|
||||
userName: {
|
||||
flex: 1,
|
||||
color: Color.text,
|
||||
fontSize: 16
|
||||
},
|
||||
removeIcon: {
|
||||
padding: 20
|
||||
}
|
||||
});
|
|
@ -122,6 +122,14 @@ export default class DiaryList extends Component {
|
|||
});
|
||||
}
|
||||
|
||||
filter(blockUserId) {
|
||||
let diaries = this.state.diaries;
|
||||
let filtered = diaries.filter(d => d.user.id != blockUserId);
|
||||
this.setState({
|
||||
diaries: filtered
|
||||
});
|
||||
}
|
||||
|
||||
refreshOne(index, diary) {
|
||||
if(diary) {
|
||||
let list = this.state.diaries;
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import React, {Component} from 'react';
|
||||
import {StyleSheet, Text, View, ScrollView, InteractionManager} from 'react-native';
|
||||
import {Avatar} from "react-native-elements";
|
||||
import {StyleSheet, Text, View, ScrollView, InteractionManager, Alert} from 'react-native';
|
||||
import {Avatar, Button} from "react-native-elements";
|
||||
import moment from 'moment';
|
||||
|
||||
import Color from '../style/color';
|
||||
import Api from '../util/api';
|
||||
import Msg from '../util/msg';
|
||||
|
||||
import UserIcon from './userIcon'
|
||||
import Loading from './loading'
|
||||
import UserIcon from './userIcon';
|
||||
import Loading from './loading';
|
||||
|
||||
|
||||
export default class UserIntro extends Component {
|
||||
|
@ -18,24 +18,54 @@ export default class UserIntro extends Component {
|
|||
|
||||
this.state = {
|
||||
user: props.user,
|
||||
followed: 0,
|
||||
|
||||
isLoading: true
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
Api.getSelfInfoByStore()
|
||||
.then(user => {
|
||||
this.selfInfo = user;
|
||||
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
this.refresh();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
refresh() {
|
||||
let userId = this.state.user ? this.state.user.id : this.selfInfo.id;
|
||||
Api.getUserInfo(userId)
|
||||
_onAddFollow() {
|
||||
Api.addFollow(this.state.user.id)
|
||||
.then(() => {
|
||||
this.setState({
|
||||
followed: 1
|
||||
});
|
||||
|
||||
Alert.alert('已关注');
|
||||
})
|
||||
.catch(e => {
|
||||
Alert.alert('关注失败');
|
||||
})
|
||||
}
|
||||
|
||||
_onDeleteFollow() {
|
||||
Api.deleteFollow(this.state.user.id)
|
||||
.then(() => {
|
||||
this.setState({
|
||||
followed: -1,
|
||||
});
|
||||
|
||||
Alert.alert('已取消关注');
|
||||
})
|
||||
.catch(e => {
|
||||
Alert.alert('取消关注失败');
|
||||
})
|
||||
}
|
||||
|
||||
refresh(userId) {
|
||||
let targetId = userId;
|
||||
if(!targetId) {
|
||||
targetId = this.state.user ? this.state.user.id : null;
|
||||
}
|
||||
|
||||
if(targetId) {
|
||||
Api.getUserInfo(targetId)
|
||||
.then(user => {
|
||||
this.setState({
|
||||
user: user
|
||||
|
@ -50,6 +80,15 @@ export default class UserIntro extends Component {
|
|||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
refreshFollowed(followed = 0) {
|
||||
if(followed) {
|
||||
this.setState({
|
||||
followed: followed
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
if(this.state.isLoading) {
|
||||
|
@ -57,10 +96,34 @@ export default class UserIntro extends Component {
|
|||
}
|
||||
|
||||
const user = this.state.user;
|
||||
const followed = this.state.followed;
|
||||
|
||||
return user ? (
|
||||
<ScrollView style={localStyle.container} automaticallyAdjustContentInsets={false}>
|
||||
<View style={localStyle.userIcon}>
|
||||
<UserIcon width={90} height={90} iconUrl={user.coverUrl} />
|
||||
|
||||
{
|
||||
followed < 0
|
||||
? <Button title="+关注"
|
||||
outline={true}
|
||||
color={Color.primary}
|
||||
borderRadius={5}
|
||||
buttonStyle={localStyle.followButton}
|
||||
onPress={this._onAddFollow.bind(this)}
|
||||
/>
|
||||
: (
|
||||
followed > 0
|
||||
? <Button title="取消关注"
|
||||
backgroundColor={Color.primary}
|
||||
borderRadius={5}
|
||||
buttonStyle={localStyle.followButton}
|
||||
onPress={this._onDeleteFollow.bind(this)}
|
||||
/>
|
||||
: null
|
||||
)
|
||||
}
|
||||
|
||||
<Text style={localStyle.userTitle}>{user.name}</Text>
|
||||
</View>
|
||||
|
||||
|
@ -89,6 +152,14 @@ const localStyle = StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
followButton: {
|
||||
width: 100,
|
||||
height: 30,
|
||||
marginTop: 20,
|
||||
marginRight: 3,
|
||||
paddingTop: 5,
|
||||
paddingBottom: 5,
|
||||
},
|
||||
userTitle: {
|
||||
fontSize: 22,
|
||||
marginTop: 30,
|
||||
|
|
49
src/page/BlockUserPage.js
Normal file
49
src/page/BlockUserPage.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
import React, {Component} from 'react';
|
||||
import {StyleSheet, Text, View} from 'react-native';
|
||||
|
||||
import BlockUserList from '../component/block/blockUserList';
|
||||
|
||||
|
||||
export default class BlockUserPage extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
static options(passProps) {
|
||||
return {
|
||||
topBar: {
|
||||
title: {
|
||||
text: '屏蔽'
|
||||
}
|
||||
},
|
||||
statusBar: {
|
||||
backgroundColor: 'white',
|
||||
style: 'dark'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={localStyle.wrap}>
|
||||
<BlockUserList ref={(r) => this.list = r}
|
||||
{...this.props}
|
||||
></BlockUserList>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const localStyle = StyleSheet.create({
|
||||
wrap: {
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
paddingTop: 1
|
||||
}
|
||||
});
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
import React, {Component} from 'react';
|
||||
import {StyleSheet, Text, View} from 'react-native';
|
||||
import {StyleSheet, Text, View, DeviceEventEmitter} from 'react-native';
|
||||
import {Navigation} from 'react-native-navigation';
|
||||
|
||||
import Api from '../util/api';
|
||||
import Event from "../util/event";
|
||||
import {Icon} from '../style/icon';
|
||||
import Color from '../style/color';
|
||||
|
||||
|
@ -64,6 +65,15 @@ export default class FollowPage extends Component {
|
|||
}
|
||||
}
|
||||
);
|
||||
|
||||
this.blockUserListener = DeviceEventEmitter.addListener(Event.userBlocked, (param) => {
|
||||
this.diaryList.filter(param.blockUserId);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.bottomTabEventListener.remove();
|
||||
this.blockUserListener.remove();
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, {Component} from 'react';
|
||||
import {StyleSheet, Text, View, Animated} from 'react-native';
|
||||
import {StyleSheet, Text, View, Animated, DeviceEventEmitter} from 'react-native';
|
||||
import {
|
||||
PagerScroll,
|
||||
TabView,
|
||||
|
@ -8,7 +8,9 @@ import {
|
|||
} from 'react-native-tab-view';
|
||||
|
||||
import Api from '../util/api';
|
||||
import Event from "../util/event";
|
||||
import Color from '../style/color';
|
||||
|
||||
import FollowUserList from '../component/follow/followUserList'
|
||||
import FollowingUserData from '../dataLoader/followingUserData'
|
||||
import FollowedByUserData from '../dataLoader/followedByUserData'
|
||||
|
@ -44,6 +46,21 @@ export default class FollowUserPage extends Component {
|
|||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.blockUserListener = DeviceEventEmitter.addListener(Event.userBlocked, (param) => {
|
||||
if (this.followingList) {
|
||||
this.followingList.refresh();
|
||||
}
|
||||
if (this.folloedByList) {
|
||||
this.folloedByList.refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.blockUserListener.remove();
|
||||
}
|
||||
|
||||
_renderLabel = props => ({route}) => {
|
||||
let routes = props.navigationState.routes;
|
||||
let index = props.navigationState.index;
|
||||
|
@ -72,14 +89,14 @@ export default class FollowUserPage extends Component {
|
|||
};
|
||||
|
||||
_renderScene = SceneMap({
|
||||
following: () => <FollowUserList
|
||||
following: () => <FollowUserList ref={(r) => this.followingList = r}
|
||||
listType={'followingUser'} dataSource={new FollowingUserData()}
|
||||
onDeletePress={async (id) => {
|
||||
return Api.deleteFollow(id);
|
||||
}}
|
||||
{...this.props}
|
||||
/>,
|
||||
followedBy: () => <FollowUserList
|
||||
followedBy: () => <FollowUserList ref={(r) => this.followedByList = r}
|
||||
listType={'followedByUser'} dataSource={new FollowedByUserData()}
|
||||
onDeletePress={async (id) => {
|
||||
return Api.deleteFollowBy(id);
|
||||
|
|
|
@ -9,7 +9,8 @@ import {
|
|||
Modal,
|
||||
TouchableWithoutFeedback,
|
||||
InteractionManager,
|
||||
StatusBar
|
||||
StatusBar,
|
||||
DeviceEventEmitter,
|
||||
} from 'react-native';
|
||||
import {Navigation} from 'react-native-navigation';
|
||||
import {Button} from 'react-native-elements';
|
||||
|
@ -18,6 +19,7 @@ import ActionSheet from 'react-native-actionsheet-api';
|
|||
import Color from '../style/color'
|
||||
import Api from '../util/api';
|
||||
import Update from '../util/update';
|
||||
import Event from '../util/event'
|
||||
|
||||
import DiaryList from '../component/diary/diaryList'
|
||||
import HomeDiaryData from '../dataLoader/homeDiaryData';
|
||||
|
@ -76,10 +78,15 @@ export default class HomePage extends Component {
|
|||
Update.updateAndroid();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
this.blockUserListener = DeviceEventEmitter.addListener(Event.userBlocked, (param) => {
|
||||
this.diaryList.filter(param.blockUserId);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.bottomTabEventListener.remove();
|
||||
this.blockUserListener.remove();
|
||||
}
|
||||
|
||||
startTimer() {
|
||||
|
|
|
@ -179,6 +179,13 @@ export default class SettingPage extends Component {
|
|||
{/*</View>*/}
|
||||
</View>
|
||||
|
||||
<View style={localStyle.group}>
|
||||
<TouchableOpacity style={localStyle.item} onPress={() => this.jumpTo('BlockUser')}>
|
||||
<Text style={localStyle.title}>屏蔽</Text>
|
||||
<Ionicons name="ios-arrow-forward" style={localStyle.arrow} size={18}/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<View style={localStyle.group}>
|
||||
{
|
||||
Api.IS_IOS ? (
|
||||
|
|
|
@ -61,10 +61,14 @@ export default class TopicPage extends Component {
|
|||
this.diaryListener = DeviceEventEmitter.addListener(Event.updateDiarys, (param) => {
|
||||
this.diaryList.refresh();
|
||||
});
|
||||
this.blockUserListener = DeviceEventEmitter.addListener(Event.userBlocked, (param) => {
|
||||
this.diaryList.filter(param.blockUserId);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.diaryListener.remove();
|
||||
this.blockUserListener.remove();
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
} from 'react-native-tab-view';
|
||||
import {Navigation} from 'react-native-navigation';
|
||||
|
||||
import Msg from '../util/msg';
|
||||
import Api from '../util/api';
|
||||
import {Icon} from '../style/icon';
|
||||
import Event from "../util/event";
|
||||
|
@ -48,8 +49,8 @@ export default class UserPage extends Component {
|
|||
text: passProps.user.name
|
||||
},
|
||||
rightButtons: [{
|
||||
id: 'followIcon',
|
||||
icon: Icon.navButtonFollow
|
||||
id: 'navButtonMore',
|
||||
icon: Icon.navButtonMore
|
||||
}]
|
||||
},
|
||||
statusBar: {
|
||||
|
@ -76,42 +77,27 @@ export default class UserPage extends Component {
|
|||
}
|
||||
|
||||
navigationButtonPressed({buttonId}) {
|
||||
if(buttonId == 'followIcon') {
|
||||
Api.addFollow(this.userId)
|
||||
.then(() => {
|
||||
Navigation.mergeOptions(this.props.componentId, {
|
||||
topBar: {
|
||||
rightButtons: [{
|
||||
id: 'navButtonFollowSelected',
|
||||
icon: Icon.navButtonFollowSelected
|
||||
}]
|
||||
}
|
||||
});
|
||||
if(buttonId == 'navButtonMore') {
|
||||
ActionSheet.showActionSheetWithOptions({
|
||||
options: ['屏蔽', '取消'],
|
||||
cancelButtonIndex: 1,
|
||||
destructiveButtonIndex: 0
|
||||
|
||||
Alert.alert('已关注');
|
||||
}, (index) => {
|
||||
if(index == 0) {
|
||||
Api.addUserBlock(this.userId)
|
||||
.then(() => {
|
||||
DeviceEventEmitter.emit(Event.userBlocked, {blockUserId: this.userId});
|
||||
Navigation.popToRoot(this.props.componentId);
|
||||
Msg.showMsg('该用户已被屏蔽');
|
||||
})
|
||||
.catch(e => {
|
||||
Alert.alert('关注失败');
|
||||
})
|
||||
|
||||
} else if(buttonId == 'navButtonFollowSelected') {
|
||||
Api.deleteFollow(this.userId)
|
||||
.then(() => {
|
||||
Navigation.mergeOptions(this.props.componentId, {
|
||||
topBar: {
|
||||
rightButtons: [{
|
||||
id: 'followIcon',
|
||||
icon: Icon.navButtonFollow
|
||||
}]
|
||||
console.log('block error:', e);
|
||||
Alert.alert('屏蔽失败');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Alert.alert('已取消关注');
|
||||
})
|
||||
.catch(e => {
|
||||
Alert.alert('取消关注失败');
|
||||
})
|
||||
|
||||
} else if(buttonId == 'setting') {
|
||||
Navigation.push(this.props.componentId, {
|
||||
component: {
|
||||
|
@ -131,10 +117,10 @@ export default class UserPage extends Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
if(this.userId) {
|
||||
Api.getSelfInfoByStore()
|
||||
.then(user => {
|
||||
if(user && user.id == this.userId) {
|
||||
if(!this.userId || (user && user.id == this.userId)) {
|
||||
this.userIntro.refresh(user.id);
|
||||
Navigation.mergeOptions(this.props.componentId, {
|
||||
topBar: {
|
||||
rightButtons: [{
|
||||
|
@ -143,24 +129,15 @@ export default class UserPage extends Component {
|
|||
}]
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
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.followed = re ? 1 : -1;
|
||||
this.userIntro.refreshFollowed(this.followed);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.notebookListener = DeviceEventEmitter.addListener(Event.updateNotebooks, (param) => {
|
||||
this.notebookList.refresh();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export default {
|
||||
About: require("./AboutPage.js").default,
|
||||
BlockUser: require("./BlockUserPage.js").default,
|
||||
DiaryDetail: require("./DiaryDetailPage.js").default,
|
||||
Empty: require("./EmptyPage.js").default,
|
||||
Feedback: require("./FeedbackPage.js").default,
|
||||
|
|
|
@ -369,16 +369,16 @@ async function getUpdateInfo() {
|
|||
}
|
||||
|
||||
async function addUserBlock(user_id) {
|
||||
return call('POST', `blocks/${user_id}`);
|
||||
return call('POST', `/blocks/${user_id}`);
|
||||
}
|
||||
|
||||
|
||||
async function deleteUserBlock(user_id) {
|
||||
return call('DELETE', `blocks/${user_id}`);
|
||||
return call('DELETE', `/blocks/${user_id}`);
|
||||
}
|
||||
|
||||
async function getBlockUsers() {
|
||||
return call('GET', `blocks`);
|
||||
return call('GET', `/blocks`);
|
||||
}
|
||||
|
||||
export async function updatePushInfo() {
|
||||
|
|
|
@ -7,5 +7,7 @@ export default {
|
|||
commentPressed: 'commentPressed',
|
||||
passwordUpdated: 'passwordUpdated',
|
||||
updateNewsRead: 'updateNewsRead',
|
||||
userInfoUpdated: 'userInfoUpdated'
|
||||
userInfoUpdated: 'userInfoUpdated',
|
||||
|
||||
userBlocked: 'userBlocked',
|
||||
}
|
Loading…
Reference in a new issue