1. 写日记页面选择日记本模态框

2. 关注/被关注用户删除
This commit is contained in:
xuwenyang 2019-05-22 01:27:37 +08:00
parent 3d44a3aaf5
commit d862735d6f
6 changed files with 282 additions and 12 deletions

View file

@ -1,5 +1,6 @@
import React, {Component} from 'react';
import {StyleSheet, Text, View, InteractionManager, FlatList} from 'react-native';
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';
@ -35,6 +36,41 @@ export default class FollowUserList extends Component {
});
}
_onItemPress(user) {
Navigation.push(this.props.componentId, {
component: {
name: 'User',
options: {
bottomTabs: {
visible: false,
// hide bottom tab for android
drawBehind: true,
animate: true
}
},
passProps: {
user: user
}
}
});
}
_onDeletePress(user) {
Alert.alert('提示', '确定删除关注?', [
{text: '删除', style: 'destructive', onPress: () => {
this.props.onDeletePress(user.id)
.done(() => {
let filterUsers = this.state.users.filter((it) => it.id !== user.id);
this.setState({
users: filterUsers
});
});
}},
{text: '取消', onPress: () => {}}
]);
}
refresh() {
if (this.state.refreshing) {
return;
@ -119,11 +155,11 @@ export default class FollowUserList extends Component {
renderItem={({item}) => {
return (
<Touchable key={item.id} onPress={() => {}}>
<Touchable key={item.id} onPress={() => this._onItemPress(item)}>
<View style={localStyle.box}>
<UserIcon iconUrl={item.iconUrl}></UserIcon>
<Text style={localStyle.userName}>{item.name}</Text>
<Touchable onPress={() => {}}>
<Touchable onPress={() => this._onDeletePress(item)}>
<Ionicons name="md-close" size={20}
style={localStyle.removeIcon}
color={Color.inactiveText} />

View file

@ -1,5 +1,5 @@
import React, {Component} from 'react';
import {View, StyleSheet, Text, Image, ImageBackground, TouchableOpacity} from 'react-native';
import {View, StyleSheet, Text, Image, ImageBackground} from 'react-native';
import Api from '../../util/api';
import Color from '../../style/color'

View file

@ -0,0 +1,92 @@
import React, { Component } from 'react';
import {
View,
Text,
ScrollView,
StyleSheet,
Alert,
InteractionManager,
TouchableOpacity
} from 'react-native';
import Api from '../../util/api';
import Notebook from './notebook'
export default class NotebookLine extends Component {
constructor(props) {
super(props);
this.state = {
notebooks: []
};
}
componentDidMount(){
InteractionManager.runAfterInteractions(() => {
this.load();
});
}
load() {
Api.getSelfNotebooks()
.then(notebooks => {
if(!notebooks || !notebooks.filter) {
notebooks = [];
}
const unExpiredBooks = notebooks.filter(it => !it.isExpired);
if(unExpiredBooks.length === 0) {
Alert.alert('提示', '没有可用日记本,无法写日记', [
{text: '取消', onPress: () => {}},
{text: '创建一个', onPress: () => {}}
]);
}
this.setState({
notebooks: unExpiredBooks
});
}).done(() => {});
}
render() {
return (
<ScrollView horizontal={true}
contentContainerStyle={localStyle.container}
keyboardDismissMode='on-drag'
keyboardShouldPersistTaps='always'
snapToAlignment='start'
snapToInterval={300}
decelerationRate={0}
showsHorizontalScrollIndicator={true}
>
{
this.state.notebooks.map((notebook) => {
return (
<TouchableOpacity key={notebook.id} activeOpacity={0.7}
onPress={this.props.onNotebookPress}>
<Notebook key={notebook.id} style={{paddingRight: 10}}
notebook={notebook} />
</TouchableOpacity>
);
})
}
</ScrollView>
);
}
}
const localStyle = StyleSheet.create({
container: {
padding: 10,
paddingRight: 0,
paddingBottom:0
}
});

View file

@ -14,7 +14,7 @@ import FollowingUserData from '../dataLoader/followingUserData'
import FollowedByUserData from '../dataLoader/followedByUserData'
export default class FollowPage extends Component {
export default class FollowUserPage extends Component {
constructor(props) {
super(props);
@ -70,9 +70,17 @@ export default class FollowPage extends Component {
_renderScene = SceneMap({
following: () => <FollowUserList
listType={'followingUser'} dataSource={new FollowingUserData()}
onDeletePress={async (id) => {
return Api.deleteFollow(id);
}}
{...this.props}
/>,
followedBy: () => <FollowUserList
listType={'followedByUser'} dataSource={new FollowedByUserData()}
onDeletePress={async (id) => {
return Api.deleteFollowBy(id);
}}
{...this.props}
/>
});

View file

@ -1,5 +1,16 @@
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, ScrollView, TextInput, TouchableOpacity} from 'react-native';
import {
StyleSheet,
Text,
View,
ScrollView,
TextInput,
TouchableOpacity,
Modal,
Animated,
Easing,
TouchableWithoutFeedback
} from 'react-native';
import {Navigation} from 'react-native-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';
@ -7,6 +18,8 @@ import {Icon} from '../style/icon'
import Color from '../style/color'
import Api from '../util/api'
import NotebookLine from '../component/notebook/notebookLine'
export default class WritePage extends Component {
@ -15,7 +28,11 @@ export default class WritePage extends Component {
Navigation.events().bindComponent(this);
this.state = {
content: ''
content: '',
modalVisible: false,
fadeAnimOpacity: new Animated.Value(0),
fadeAnimHeight: new Animated.Value(0)
}
}
@ -44,6 +61,40 @@ export default class WritePage extends Component {
};
}
openModal() {
this.setState({modalVisible: true});
}
closeModal(showKeyboard = true) {
this.contentInput.blur();
Animated.parallel([
Animated.timing(
this.state.fadeAnimOpacity,
{
toValue: 0,
duration: 350,
easing: Easing.out(Easing.cubic)
}
),
Animated.timing(
this.state.fadeAnimHeight,
{
toValue: 0,
duration: 350,
easing: Easing.out(Easing.cubic)
}
)
]).start(({finished}) => {
this.setState({modalVisible: false});
if(!finished) {
return;
}
if(showKeyboard) {
setTimeout(() => this.contentInput.focus(), 100);
}
});
}
render() {
return (
<ScrollView style={localStyle.container}
@ -68,7 +119,7 @@ export default class WritePage extends Component {
/>
<View style={localStyle.bottomBar}>
<TouchableOpacity onPress={() => {}}>
<TouchableOpacity onPress={this.openModal.bind(this)}>
<View style={localStyle.notebookButton}>
<Ionicons name='ios-bookmarks-outline' size={16}
color={Color.text} style={{marginTop: 2, marginRight: 6}} />
@ -88,9 +139,63 @@ export default class WritePage extends Component {
</TouchableOpacity>
</View>
{this.renderModal()}
</ScrollView>
);
}
renderModal() {
return (
<Modal animationType='none' transparent={true}
visible={this.state.modalVisible}
onShow={() => {
Animated.parallel([
Animated.timing(
this.state.fadeAnimOpacity,
{
toValue: 0.4,
duration: 350,
easing: Easing.out(Easing.cubic)
}
),
Animated.timing(
this.state.fadeAnimHeight,
{
toValue: Api.IS_IOS
? (Api.IS_IPHONEX ? 280 : 250)
: 260,
duration: 350,
easing: Easing.out(Easing.cubic)
}
)
]).start();
}}
onRequestClose={() => {}}
>
<View style={{flex: 1}}>
<TouchableWithoutFeedback onPress={this.closeModal.bind(this)} style={{flex: 1}}>
<Animated.View style={{ flex: 1, backgroundColor: "black", opacity: this.state.fadeAnimOpacity }} />
</TouchableWithoutFeedback>
<Animated.View style={{height: this.state.fadeAnimHeight, backgroundColor: '#fff'}}>
<View style={localStyle.modalBanner}>
<TouchableOpacity onPress={() => {}} style={localStyle.modalButton}>
<Text style={localStyle.modalButtonText}>新添</Text>
</TouchableOpacity>
<Text style={{padding: 10, color: Color.text}}>选择日记本</Text>
<TouchableOpacity onPress={this.closeModal.bind(this)} style={localStyle.modalButton}>
<Text style={localStyle.modalButtonText}>取消</Text>
</TouchableOpacity>
</View>
<NotebookLine onNotebookPress={() => {}}></NotebookLine>
</Animated.View>
</View>
</Modal>
);
}
}
const localStyle = StyleSheet.create({
@ -138,5 +243,22 @@ const localStyle = StyleSheet.create({
height: 40,
alignItems: "center",
justifyContent: 'center'
},
modalBanner: {
flexDirection: 'row',
justifyContent: 'space-between',
borderTopColor: '#e2e2e2',
borderTopWidth: StyleSheet.hairlineWidth,
borderBottomColor: '#e2e2e2',
borderBottomWidth: StyleSheet.hairlineWidth
},
modalButton: {
paddingHorizontal: 15,
paddingVertical: 10
},
modalButtonText: {
color: Color.light,
fontSize: 15,
}
});

View file

@ -6,6 +6,7 @@ import TokenManager from './token'
const IS_ANDROID = Platform.OS === 'android';
const IS_IOS = Platform.OS === 'ios';
const DEVICE_WINDOW = Dimensions.get('window')
const OS = DeviceInfo.getSystemName();
@ -45,6 +46,14 @@ async function getSelfInfo() {
return call('GET', '/users/my');
}
async function getSelfInfoByStore() {
return await TokenManager.getUserInfo();
}
async function getUserInfo(id) {
return call('GET', '/users/' + id)
}
async function getTodayDiaries(page = 1, page_size = 20, first_id = '') {
return call('GET', '/diaries/today?page=' + page + '&page_size=' + page_size + `&first_id=${first_id}`)
.then((json) => {
@ -99,12 +108,12 @@ async function getRelationReverseUsers(page, page_size) {
return call('GET', `/relation/reverse?page=${page}&page_size=${page_size}`);
}
async function getSelfInfoByStore() {
return await TokenManager.getUserInfo();
async function deleteFollow(user_id) {
return call('DELETE', '/relation/' + user_id);
}
async function getUserInfo(id) {
return call('GET', '/users/' + id)
async function deleteFollowBy(user_id) {
return call('DELETE', '/relation/reverse/' + user_id);
}
async function getMessagesHistory() {
@ -191,6 +200,7 @@ function handleCatch(err) {
export default {
IS_ANDROID,
IS_IOS,
DEVICE_WINDOW,
OS,
OS_VERSION,
@ -214,6 +224,8 @@ export default {
getRelationUsers,
getRelationReverseUsers,
deleteFollow,
deleteFollowBy,
getMessagesHistory
}