1. 日记本全部日记列表

2. android更新react-native-vector-icons的font文件
This commit is contained in:
xuwenyang 2019-05-17 19:14:26 +08:00
parent 0b682dd777
commit 762c46eead
20 changed files with 344 additions and 49 deletions

View file

@ -19,15 +19,21 @@ export default class DiaryBrief extends Component {
return ( return (
<View style={localStyle.box}> <View style={localStyle.box}>
<UserIcon iconUrl={user.iconUrl}></UserIcon> {(user && user.iconUrl)
? <UserIcon iconUrl={user.iconUrl}></UserIcon> : null}
<View style={localStyle.body}> <View style={localStyle.body}>
<View style={localStyle.title}> <View style={localStyle.title}>
<Text style={localStyle.titleName} numberOfLines={1}> {(user && user.name)
? ( <Text style={localStyle.titleName} numberOfLines={1}>
{user.name} {user.name}
</Text> </Text>
<Text style={[localStyle.titleText, {flex: 1}]} numberOfLines={1}> ) : null}
{(user && user.name)
? ( <Text style={[localStyle.titleText, {flex: 1}]} numberOfLines={1}>
{diary.notebook_subject} {diary.notebook_subject}
</Text> </Text>
) : null}
<Text style={localStyle.titleText}> <Text style={localStyle.titleText}>
{moment(diary.created).format('H:mm')} {moment(diary.created).format('H:mm')}
</Text> </Text>
@ -99,7 +105,7 @@ const localStyle = StyleSheet.create({
alignItems: "center", alignItems: "center",
width: '100%', width: '100%',
height: 30, height: 30,
marginTop: 5, marginTop: 10,
justifyContent: 'space-between' justifyContent: 'space-between'
} }
}); });

View file

@ -17,10 +17,6 @@ export default class Notebook extends Component {
let notebook = this.props.notebook; let notebook = this.props.notebook;
return ( return (
<TouchableOpacity key={notebook.id} style={localStyle.container}
activeOpacity={0.7}
onPress={() => {}}>
<View style={Api.IS_ANDROID ? localStyle.androidBox : localStyle.iosBox}> <View style={Api.IS_ANDROID ? localStyle.androidBox : localStyle.iosBox}>
<ImageBackground key={notebook.id} <ImageBackground key={notebook.id}
style={localStyle.cover} imageStyle={{resizeMode: 'cover'}} style={localStyle.cover} imageStyle={{resizeMode: 'cover'}}
@ -40,23 +36,19 @@ export default class Notebook extends Component {
{notebook.created}{notebook.expired} {notebook.created}{notebook.expired}
</Text> </Text>
</View> </View>
</View> </View>
</TouchableOpacity>
); );
} }
} }
const localStyle = StyleSheet.create({ const localStyle = StyleSheet.create({
container: {
marginBottom: 15
},
androidBox: { androidBox: {
width: 140, width: 140,
elevation: 1, elevation: 1,
backgroundColor: '#fff', backgroundColor: '#fff',
alignItems: 'center', alignItems: 'center',
margin: 3 margin: 3,
marginBottom: 15
}, },
iosBox: { iosBox: {
width: 140, width: 140,
@ -65,7 +57,8 @@ const localStyle = StyleSheet.create({
shadowOffset: {width: 0, height: 0}, shadowOffset: {width: 0, height: 0},
backgroundColor: '#fff', backgroundColor: '#fff',
alignItems: 'center', alignItems: 'center',
margin: 3 margin: 3,
marginBottom: 15
}, },
privateLabel: { privateLabel: {
position: 'absolute', position: 'absolute',

View file

@ -0,0 +1,216 @@
import React, {Component} from 'react';
import {
View,
StyleSheet,
Text,
SectionList,
InteractionManager,
TouchableOpacity,
ActivityIndicator
} from 'react-native';
import moment from 'moment'
import Api from '../../util/api';
import Color from '../../style/color';
import Touchable from '../touchable';
import DiaryBrief from '../diary/diaryBrief';
import NotebookDiaryData from '../../dataLoader/notebookDiaryData';
export default class NotebookDiaryList extends Component {
constructor(props) {
super(props);
this.dataSource = new NotebookDiaryData();
this.notebook = props.notebook;
this.state = {
diaries: [],
hasMore: false,
refreshing: false,
refreshFailed: false
};
}
componentDidMount(){
InteractionManager.runAfterInteractions(() => {
this.refresh();
});
}
formatDiaries(diaries) {
let today = moment().format('YYYY年M月D日');
let reducedDiaries = diaries.reduce((maplist, item) => {
let [year, month, day] =
item.created.substr(0, 10).split('-')
.map(it => Number(it));
let date = `${year}${month}${day}`;
if(date === today) {
date = '今天';
}
if(!maplist[date]) {
maplist[date] = [];
}
maplist[date].push(item);
return maplist;
}, {});
console.log('reduce result:', reducedDiaries);
let result = [];
for(let key in reducedDiaries) {
result.push({
title: key,
data: reducedDiaries[key]
});
}
console.log('format result:', result);
return result;
}
refresh(loadMore = false) {
this.setState({refreshing: true});
this.dataSource.refresh(this.notebook.id, loadMore)
.then(result => {
console.log('get notebook diaries:', result);
if(!result) {
throw {
message: 'refresh no result'
}
} else {
let diaries = this.formatDiaries(result.list);
this.setState({
diaries,
hasMore: result.more,
refreshFailed: false
});
}
}).catch(e => {
this.setState({
diaries: [],
hasMore: false,
refreshFailed: true
});
}).done(() => {
this.setState({
refreshing: false
});
});
}
loadMore() {
if (this.state.refreshing) {
return;
}
this.refresh(true);
}
render() {
return this.notebook ? (
<View style={localStyle.container}>
<SectionList
keyExtractor={(item, index) => item.id}
sections={this.state.diaries}
renderItem={(rowData) => {
return (<Touchable onPress={() => {}}>
<DiaryBrief diary={rowData.item}></DiaryBrief>
</Touchable>);
}}
renderSectionHeader={(info) => {
return (<View style={localStyle.sectionHeader}>
<Text>{info.section.title}</Text>
</View>);
}}
ListFooterComponent={this.renderFooter.bind(this)}
automaticallyAdjustContentInsets={true}
ItemSeparatorComponent={(sectionID, rowID, adjacentRowHighlighted) =>
<View key={`${sectionID}-${rowID}`} style={localStyle.itemSeparator} />}
SectionSeparatorComponent={() => <View style={localStyle.sectionSeparator} />}
onEndReached={this.state.hasMore ? this.loadMore.bind(this) : null}
/>
</View>
) : null;
}
renderFooter() {
if (this.state.refreshing || this.state.diaries.length === 0) {
return null;
}
if (this.state.refreshFailed) {
return (
<View style={localStyle.footer}>
<TouchableOpacity style={{marginTop: 15}}
onPress={() => {this.loadMore();}}>
<Text style={{color: Color.primary}}>加载失败,请点击重试</Text>
</TouchableOpacity>
</View>
);
}
if (!this.state.hasMore) {
return (
<View style={localStyle.footer}>
<Text style={{color: Color.inactiveText, fontSize: 12}}> THE END </Text>
</View>
);
}
return (
<View style={localStyle.footer}>
<ActivityIndicator animating={true} color={Color.primary}
size={Api.IS_ANDROID ? 'large' : 'small'}/>
</View>
);
}
}
const localStyle = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white'
},
sectionHeader: {
backgroundColor: '#F9F9F9',
paddingHorizontal: 15,
paddingVertical: 8,
color: Color.text
},
itemSeparator: {
borderBottomWidth: StyleSheet.hairlineWidth,
borderColor: Color.line
},
sectionSeparator: {
borderBottomWidth: StyleSheet.hairlineWidth,
borderColor: Color.line
},
footer: {
height: 60,
justifyContent: 'center',
alignItems: 'center',
paddingBottom: 15
}
});

View file

@ -5,7 +5,8 @@ import {
Text, Text,
FlatList, FlatList,
StyleSheet, StyleSheet,
RefreshControl RefreshControl,
TouchableOpacity
} from 'react-native'; } from 'react-native';
import Api from '../../util/api'; import Api from '../../util/api';
@ -72,11 +73,14 @@ export default class NotebookList extends Component {
} }
_renderItem(notebook) { _renderItem(notebook) {
return notebook ? ( return notebook ? (
<Notebook key={notebook.id} notebook={notebook} onPress={() => {}} /> <TouchableOpacity key={notebook.id} activeOpacity={0.7}
) : null onPress={() => this.props.onNotebookPress(notebook)}>
<Notebook key={notebook.id} notebook={notebook} />
</TouchableOpacity>
) : null
} }
render() { render() {

View file

@ -3,7 +3,7 @@ import Api from '../util/api'
const PAGE_SIZE = 21; const PAGE_SIZE = 21;
export default class FollowListData { export default class FollowDiaryData {
list: []; list: [];
last_id: 0; last_id: 0;

View file

@ -1,7 +1,7 @@
import Api from '../util/api' import Api from '../util/api'
const PAGE_SIZE = 20; const PAGE_SIZE = 21;
export default class FollowedByUserData { export default class FollowedByUserData {

View file

@ -1,7 +1,7 @@
import Api from '../util/api' import Api from '../util/api'
const PAGE_SIZE = 20; const PAGE_SIZE = 21;
export default class FollowingUserData { export default class FollowingUserData {

View file

@ -3,7 +3,7 @@ import Api from '../util/api'
const PAGE_SIZE = 21; const PAGE_SIZE = 21;
export default class HomeListData { export default class HomeDiaryData {
list: []; list: [];
last_id: 0; last_id: 0;

View file

@ -0,0 +1,30 @@
import Api from '../util/api'
const PAGE_SIZE = 21;
export default class NotebookDiaryData {
page: 1;
list: [];
async refresh(notebookId, loadMore = false) {
let page = !loadMore ? 1 : this.page + 1;
let data = await Api.getNotebookDiaries(notebookId, page, PAGE_SIZE);
let more = data.items.length === PAGE_SIZE;
if(!loadMore) {
this.page = page;
this.list = data.items.slice(0, PAGE_SIZE - 1);
} else if(data.items.length > 0) {
this.page = page;
this.list = this.list.concat(data.items.slice(0, PAGE_SIZE - 1));
}
return {
list: this.list,
more
};
}
}

View file

@ -6,7 +6,7 @@ import Api from '../util/api'
import {Icon} from '../style/icon' import {Icon} from '../style/icon'
import DiaryList from '../component/diary/diaryList' import DiaryList from '../component/diary/diaryList'
import FollowListData from '../dataLoader/followListData'; import FollowListData from '../dataLoader/followDiaryData';
export default class FollowPage extends Component { export default class FollowPage extends Component {

View file

@ -5,7 +5,7 @@ import {Navigation} from 'react-native-navigation';
import Api from '../util/api'; import Api from '../util/api';
import DiaryList from '../component/diary/diaryList' import DiaryList from '../component/diary/diaryList'
import HomeListData from '../dataLoader/homeListData'; import HomeListData from '../dataLoader/homeDiaryData';
export default class HomePage extends Component { export default class HomePage extends Component {

View file

@ -0,0 +1,21 @@
import React, {Component} from 'react';
import {StyleSheet, Text, View, ScrollView} from 'react-native';
import Color from '../style/color';
import NotebookDiaryList from '../component/notebook/notebookDiaryList';
export default class NotebookDetailPage extends Component {
render() {
return (
<ScrollView style={{flex: 1}}>
<NotebookDiaryList notebook={this.props.notebook}></NotebookDiaryList>
</ScrollView>
);
}
}
const localStyle = StyleSheet.create({
});

View file

@ -6,6 +6,7 @@ import {
TabBar, TabBar,
SceneMap SceneMap
} from 'react-native-tab-view'; } from 'react-native-tab-view';
import {Navigation} from 'react-native-navigation';
import Api from '../util/api'; import Api from '../util/api';
import Color from '../style/color'; import Color from '../style/color';
@ -27,6 +28,18 @@ export default class UserPage extends Component {
}; };
} }
_onNotebookPress(notebook) {
Navigation.push(this.props.componentId, {
component: {
name: 'NotebookDetail',
passProps: {
notebook: notebook
}
}
});
}
_renderLabel = props => ({route}) => { _renderLabel = props => ({route}) => {
let routes = props.navigationState.routes; let routes = props.navigationState.routes;
let index = props.navigationState.index; let index = props.navigationState.index;
@ -58,7 +71,7 @@ export default class UserPage extends Component {
userInfo: () => <View style={localStyle.container}><Text style={localStyle.welcome}>user info !</Text></View>, userInfo: () => <View style={localStyle.container}><Text style={localStyle.welcome}>user info !</Text></View>,
diary: () => <View style={localStyle.container}><Text style={localStyle.welcome}>diary !</Text></View>, diary: () => <View style={localStyle.container}><Text style={localStyle.welcome}>diary !</Text></View>,
notebook: () => <NotebookList notebook: () => <NotebookList
onNotebookPress={this._onNotebookPress.bind(this)}
navigator={this.props.navigator} navigator={this.props.navigator}
/> />
}); });

View file

@ -3,6 +3,7 @@ DiaryDetail: require("./DiaryDetailPage.js").default,
Follow: require("./FollowPage.js").default, Follow: require("./FollowPage.js").default,
FollowUser: require("./FollowUserPage.js").default, FollowUser: require("./FollowUserPage.js").default,
Home: require("./HomePage.js").default, Home: require("./HomePage.js").default,
NotebookDetail: require("./NotebookDetailPage.js").default,
Notification: require("./NotificationPage.js").default, Notification: require("./NotificationPage.js").default,
User: require("./UserPage.js").default, User: require("./UserPage.js").default,
Write: require("./WritePage.js").default Write: require("./WritePage.js").default

View file

@ -80,6 +80,16 @@ 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 getNotebookDiaries(id, page, page_size) {
return call('GET', '/notebooks/' + id + '/diaries?page=' + page + '&page_size=' + page_size, null, 30000)
.then((json) => {
json.page = Number(json.page);
json.page_size = Number(json.page_size);
return json;
});
}
async function call(method, api, body, _timeout = 10000) { async function call(method, api, body, _timeout = 10000) {
let token = await TokenManager.getUserToken(); let token = await TokenManager.getUserToken();
@ -170,6 +180,7 @@ export default {
getTodayDiaries, getTodayDiaries,
getFollowDiaries, getFollowDiaries,
getNotebookDiaries,
getDiaryComments, getDiaryComments,
getSelfNotebooks, getSelfNotebooks,