diff --git a/src/component/diary/diaryList.js b/src/component/diary/diaryList.js index c469707..18b0268 100644 --- a/src/component/diary/diaryList.js +++ b/src/component/diary/diaryList.js @@ -112,6 +112,10 @@ export default class DiaryList extends Component { return; } + if(this.props.refreshHeader) { + this.props.refreshHeader(); + } + this.setState({refreshing: true, refreshFailed: false}); this.dataSource.refresh() .then(result => { @@ -219,6 +223,8 @@ export default class DiaryList extends Component { ItemSeparatorComponent={({highlighted}) => } + ListHeaderComponent={this.props.listHeader} + ListFooterComponent={() => { if (this.state.refreshing || this.state.loadingMore || this.state.diaries.length == 0) { return null; diff --git a/src/dataLoader/TopicDiaryData.js b/src/dataLoader/TopicDiaryData.js new file mode 100644 index 0000000..50351f1 --- /dev/null +++ b/src/dataLoader/TopicDiaryData.js @@ -0,0 +1,30 @@ +import Api from '../util/api' + + +const PAGE_SIZE = 21; + +export default class TopicDiaryData { + + list: []; + last_id: 0; + + async refresh(loadMore = false) { + let lastId = !loadMore ? 0 : this.last_id; + let data = await Api.getTodayTopicDiaries(0, PAGE_SIZE, lastId); + let more = data.diaries.length === PAGE_SIZE; + + if(!loadMore) { + this.list = data.diaries.slice(0, PAGE_SIZE - 1); + + } else if(data.diaries.length > 0) { + this.list = this.list.concat(data.diaries.slice(0, PAGE_SIZE - 1)); + } + + this.last_id = more ? data.diaries[PAGE_SIZE - 1].id : 0; + + return { + list: this.list, + more + }; + } +} \ No newline at end of file diff --git a/src/page/HomePage.js b/src/page/HomePage.js index 2a75de8..c83f627 100644 --- a/src/page/HomePage.js +++ b/src/page/HomePage.js @@ -1,7 +1,8 @@ import React, {Component} from 'react'; -import {StyleSheet, Text, View} from 'react-native'; +import {StyleSheet, Text, View, TouchableOpacity, ImageBackground} from 'react-native'; import {Navigation} from 'react-native-navigation'; +import Color from '../style/color' import Api from '../util/api'; import DiaryList from '../component/diary/diaryList' @@ -13,6 +14,41 @@ export default class HomePage extends Component { constructor(props) { super(props); this.dataSource = new HomeDiaryData(); + + this.state = { + topic: null + } + } + + refreshTopic() { + Api.getTodayTopic() + .then(topic => { + if(topic) { + this.setState({topic}); + } + }) + .done(); + } + + openTopicPage() { + Navigation.push(this.props.componentId, { + component: { + name: 'Topic', + options: { + bottomTabs: { + visible: false, + + // hide bottom tab for android + drawBehind: true, + animate: true + } + }, + passProps: { + topic: this.state.topic, + title: '话题:' + this.state.topic.title + } + } + }); } render() { @@ -20,17 +56,65 @@ export default class HomePage extends Component { this.list = r} dataSource={this.dataSource} + listHeader={this.renderHeader.bind(this)} + refreshHeader={this.refreshTopic.bind(this)} {...this.props} - > ); } + + renderHeader() { + return this.state.topic ? ( + + + + # {this.state.topic.title} + {this.state.topic.intro} + + + + ) : null; + } } const localStyle = StyleSheet.create({ wrap: { flex: 1, backgroundColor: '#fff' + }, + topic: { + paddingTop: 0 + }, + topicBox: { + flex: 1, + height: 240, + marginTop: 15, + marginBottom: 15, + marginHorizontal: 15, + backgroundColor: Color.spaceBackground, + borderRadius: 8 + }, + topicTitle: { + fontSize: 24, + color: '#FFF', + paddingHorizontal: 20, + paddingTop: 15, + paddingBottom: 10, + textShadowColor: '#000', + textShadowOffset: { width: 1, height: 1 }, + textShadowRadius: 2, + shadowOpacity: 0.2 + }, + topicIntro: { + fontSize: 16, + color: '#FFF', + paddingHorizontal: 22, + textShadowColor: '#000', + textShadowOffset: { width: 1, height: 1 }, + textShadowRadius: 2, + shadowOpacity: 0.5 } }); diff --git a/src/page/TopicPage.js b/src/page/TopicPage.js new file mode 100644 index 0000000..8de38f2 --- /dev/null +++ b/src/page/TopicPage.js @@ -0,0 +1,84 @@ +import React, {Component} from 'react'; +import {StyleSheet, Text, View, DeviceEventEmitter} from 'react-native'; +import {Navigation} from 'react-native-navigation'; + +import {Icon} from '../style/icon' +import Event from '../util/event' + +import DiaryList from '../component/diary/diaryList' +import TopicDiaryData from '../dataLoader/TopicDiaryData'; + + +export default class TopicPage extends Component { + + constructor(props) { + super(props); + + Navigation.events().bindComponent(this); + this.dataSource = new TopicDiaryData(); + } + + static options(passProps) { + return { + topBar: { + title: { + text: passProps.title + }, + rightButtons: [{ + id: 'write', + icon: Icon.navButtonWrite, + + color: '#aaa' // android + }] + } + }; + } + + navigationButtonPressed({buttonId}) { + Navigation.push(this.props.componentId, { + component: { + name: 'Write', + options: { + bottomTabs: { + visible: false, + + // hide bottom tab for android + drawBehind: true, + animate: true + } + }, + passProps: { + topic: this.props.topic + } + } + }); + } + + componentDidMount() { + this.diaryListener = DeviceEventEmitter.addListener(Event.updateDiarys, (param) => { + this.diaryList.refresh(); + }); + } + + componentWillUnmount() { + this.diaryListener.remove(); + } + + render() { + return ( + + this.diaryList = r} + dataSource={this.dataSource} + {...this.props} + > + + ); + } +} + +const localStyle = StyleSheet.create({ + wrap: { + flex: 1, + backgroundColor: '#fff' + } +}); diff --git a/src/page/WritePage.js b/src/page/WritePage.js index b048f8e..61ba114 100644 --- a/src/page/WritePage.js +++ b/src/page/WritePage.js @@ -36,6 +36,8 @@ export default class WritePage extends Component { Navigation.events().bindComponent(this); let diary = this.diary = props.diary; + let topic = this.topic = props.topic; + this.state = { notebooks: [], @@ -73,7 +75,7 @@ export default class WritePage extends Component { navigationButtonPressed({buttonId}) { if(buttonId == 'cancel') { - if(this.diary) { + if(this.diary || this.topic) { Navigation.pop(this.props.componentId); } else { @@ -250,7 +252,7 @@ export default class WritePage extends Component { Msg.showMsg('日记保存完成'); DeviceEventEmitter.emit(Event.updateDiarys); - if(this.diary) { + if(this.diary || this.topic) { Navigation.pop(this.props.componentId); } else { @@ -313,6 +315,7 @@ export default class WritePage extends Component { + {this.renderTopicButton()} {this.renderPhotoButton()} @@ -327,6 +330,20 @@ export default class WritePage extends Component { ); } + renderTopicButton() { + if(!this.topic) { + return null; + } + + return ( + + + # {this.topic.title} + + + ) + } + renderPhotoButton() { if(this.diary) { return null; diff --git a/src/page/_list.js b/src/page/_list.js index 519f9fd..12d928a 100644 --- a/src/page/_list.js +++ b/src/page/_list.js @@ -13,6 +13,7 @@ Notification: require("./NotificationPage.js").default, Password: require("./PasswordPage.js").default, Photo: require("./PhotoPage.js").default, Setting: require("./SettingPage.js").default, +Topic: require("./TopicPage.js").default, UserInfoEdit: require("./UserInfoEditPage.js").default, UserIntroEdit: require("./UserIntroEditPage.js").default, UserNameEdit: require("./UserNameEditPage.js").default, diff --git a/src/util/api.js b/src/util/api.js index bdb0638..b7b8f18 100644 --- a/src/util/api.js +++ b/src/util/api.js @@ -85,6 +85,16 @@ async function getTodayDiaries(page = 1, page_size = 20, first_id = '') { }); } +async function getTodayTopicDiaries(page = 1, page_size = 20, first_id = '') { + return call('GET', `/topic/diaries?page=${page}&page_size=${page_size}&first_id=${first_id}`) + .then((json) => { + json.page = Number(json.page); + json.page_size = Number(json.page_size); + + return json; + }); +} + async function getFollowDiaries(page = 1, page_size = 20, first_id = '') { return call('GET', '/diaries/follow?page=' + page + '&page_size=' + page_size + `&first_id=${first_id}`) .then((json) => { @@ -109,6 +119,11 @@ async function getUserTodayDiaries(userId) { return call('GET', '/users/' + userId + '/diaries/'); } +async function getTodayTopic() { + return call('GET', '/topic/'); +} + + async function getDiaryComments(diaryId) { return call('GET', '/diaries/' + diaryId + '/comments'); } @@ -389,10 +404,13 @@ export default { updateUserInfo, getTodayDiaries, + getTodayTopicDiaries, getFollowDiaries, getNotebookDiaries, getUserTodayDiaries, + getTodayTopic, + getDiary, deleteDiary,