mirror of
https://github.com/timepill/timepill-app.git
synced 2025-04-30 09:59:31 +08:00
1. 写日记页面选择日记本模态框
2. 关注/被关注用户删除
This commit is contained in:
parent
3d44a3aaf5
commit
d862735d6f
6 changed files with 282 additions and 12 deletions
|
@ -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} />
|
||||
|
|
|
@ -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'
|
||||
|
|
92
src/component/notebook/notebookLine.js
Normal file
92
src/component/notebook/notebookLine.js
Normal 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
|
||||
}
|
||||
});
|
|
@ -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}
|
||||
/>
|
||||
});
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in a new issue