1. 评论,回复

2. 写日记,隐藏底栏问题(太耗时!)
3. 其他细节补充
This commit is contained in:
xuwenyang 2019-05-28 21:36:48 +08:00
parent 44187ec26b
commit 6ff2670a3c
17 changed files with 551 additions and 108 deletions

View file

@ -1,11 +1,21 @@
import React, {Component} from 'react'; import React, {Component} from 'react';
import {StyleSheet, Text, View, ActivityIndicator, TextInput, TouchableOpacity} from 'react-native'; import {
StyleSheet,
Text,
View,
ActivityIndicator,
TextInput,
TouchableOpacity,
Alert,
DeviceEventEmitter
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons'; import Icon from 'react-native-vector-icons/Ionicons';
import KeyboardSpacer from "react-native-keyboard-spacer"; import KeyboardSpacer from "react-native-keyboard-spacer";
import Touchable from '../touchable'; import Touchable from '../touchable';
import Color from '../../style/color'; import Color from '../../style/color';
import Api from '../../util/api'; import Api from '../../util/api';
import Event from '../../util/event';
export default class CommentInput extends Component { export default class CommentInput extends Component {
@ -13,13 +23,89 @@ export default class CommentInput extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.selfInfo = props.selfInfo;
this.diary = props.diary;
this.state = { this.state = {
sending: false sending: false,
content: '',
replyUserId: 0,
replyUserName: ''
}; };
} }
componentDidMount() {
this.listener = DeviceEventEmitter.addListener(Event.commentPressed, (comment) => {
if(this.selfInfo && comment.user.id === this.selfInfo.id) {
return;
}
let content = this.state.content;
if(this.state.replyUserName) {
content = content.replace('@' + this.state.replyUserName, '@' + comment.user.name);
} else {
content = '@' + comment.user.name + ' ' + content;
}
this.setState({
content: content,
replyUserId: comment.user.id,
replyUserName: comment.user.name
});
if(this.refs.commentInput) {
// this.refs.commentInput.focus();
}
});
}
componentWillUnmount(){
this.listener.remove();
}
sendComment() { sendComment() {
this.setState({sending: true}); let content = this.state.content;
let replyUserId = this.state.replyUserId;
let replyUserName = this.state.replyUserName;
if(replyUserId && content.startsWith('@' + replyUserName + ' ')) {
content = content.substr(replyUserName.length + 2);
} else {
replyUserId = 0;
replyUserName = '';
}
if(!content) {
return;
}
this.setState({comment_sending: true});
Api.addComment(this.diary.id, content, replyUserId)
.then(result => {
if(!result) {
throw {
message: 'comment failed'
}
}
this.setState({
content: '',
replyUserId: 0,
replyUserName: ''
}, () => {
DeviceEventEmitter.emit(Event.updateComments);
});
})
.catch(e => {
Alert.alert('回复失败');
})
.done(() => {
this.setState({comment_sending: false});
});
} }
render() { render() {
@ -31,14 +117,18 @@ export default class CommentInput extends Component {
ref="commentInput" ref="commentInput"
placeholder="回复日记" placeholder="回复日记"
value={this.state.comment_content} value={this.state.content}
autoCorrect={false} autoCorrect={false}
maxLength={500} multiline={true} maxLength={500} multiline={true}
showsVerticalScrollIndicator={false} showsVerticalScrollIndicator={false}
underlineColorAndroid="transparent" underlineColorAndroid="transparent"
onChangeText={() => {}} onChangeText={(text) => {
this.setState({
content: text
})
}}
/> />
<TouchableOpacity style={localStyle.buttonWrap} <TouchableOpacity style={localStyle.buttonWrap}
onPress={this.sendComment.bind(this)}> onPress={this.sendComment.bind(this)}>
@ -75,17 +165,17 @@ const localStyle = StyleSheet.create({
borderTopWidth: StyleSheet.hairlineWidth borderTopWidth: StyleSheet.hairlineWidth
}, },
input: { input: {
flexGrow: 1,
borderColor: '#bbb', borderColor: '#bbb',
backgroundColor: '#fff', backgroundColor: '#fff',
borderWidth: StyleSheet.hairlineWidth, borderWidth: StyleSheet.hairlineWidth,
borderRadius: 19, borderRadius: 19,
paddingRight: 40, paddingRight: 40,
paddingLeft: 15, paddingLeft: 15,
paddingTop: 12, paddingTop: 10,
paddingBottom: 12, paddingBottom: 10,
fontSize: 12, height: 39,
lineHeight: 24, lineHeight: 20,
fontSize: 16,
margin: 8 margin: 8
}, },
buttonWrap: { buttonWrap: {

View file

@ -6,13 +6,16 @@ import {
FlatList, FlatList,
Text, Text,
View, View,
Alert Alert,
Keyboard,
DeviceEventEmitter
} from 'react-native'; } from 'react-native';
import {Divider} from "react-native-elements"; import {Divider} from "react-native-elements";
import Touchable from '../touchable'; import Touchable from '../touchable';
import Color from '../../style/color'; import Color from '../../style/color';
import Api from '../../util/api'; import Api from '../../util/api';
import Event from '../../util/event';
import Msg from '../../util/msg' import Msg from '../../util/msg'
import Comment from './comment'; import Comment from './comment';
@ -33,11 +36,11 @@ export default class CommentList extends Component {
componentDidMount() { componentDidMount() {
InteractionManager.runAfterInteractions(() => { InteractionManager.runAfterInteractions(() => {
this.loadMore(); this.refresh();
}); });
} }
async loadMore() { async refresh() {
let comments = await Api.getDiaryComments(this.diaryId); let comments = await Api.getDiaryComments(this.diaryId);
if(comments && comments.length > 0) { if(comments && comments.length > 0) {
if (comments.length > 1) { if (comments.length > 1) {
@ -50,6 +53,10 @@ export default class CommentList extends Component {
} }
} }
_onCommentPress(comment) {
DeviceEventEmitter.emit(Event.commentPressed, comment);
}
_onCommentAction(comment) { _onCommentAction(comment) {
ActionSheet.showActionSheetWithOptions({ ActionSheet.showActionSheetWithOptions({
options:['删除回复', '取消'], options:['删除回复', '取消'],
@ -88,7 +95,7 @@ export default class CommentList extends Component {
render() { render() {
return ( return (
<View style={localStyle.container}> <View style={localStyle.container}>
<FlatList <FlatList ref={(r) => this.list = r}
data={this.state.comments} data={this.state.comments}
@ -98,7 +105,7 @@ export default class CommentList extends Component {
renderItem={({item}) => { renderItem={({item}) => {
return ( return (
<Touchable onPress={() => {}}> <Touchable onPress={() => this._onCommentPress(item)}>
<Comment comment={item} editable={this.editable} <Comment comment={item} editable={this.editable}
onCommentAction={() => this._onCommentAction(item)}> onCommentAction={() => this._onCommentAction(item)}>
</Comment> </Comment>

View file

@ -62,7 +62,7 @@ export default class DiaryBrief extends Component {
</View> </View>
<Text style={localStyle.content} numberOfLines={5}> <Text style={localStyle.content} numberOfLines={5}>
{diary.content.trim()} {diary.content}
</Text> </Text>
<Photo uri={diary.photoThumbUrl}></Photo> <Photo uri={diary.photoThumbUrl}></Photo>

View file

@ -18,6 +18,14 @@ export default class DiaryFull extends Component {
this.editable = props.editable || false; this.editable = props.editable || false;
} }
refreshDiaryContent() {
// empty
}
async refreshComment() {
await this.commentList.refresh();
}
render() { render() {
let diary = this.diary; let diary = this.diary;
if(!diary) { if(!diary) {
@ -56,7 +64,10 @@ export default class DiaryFull extends Component {
</View> </View>
</View> </View>
<CommentList diaryId={diary.id} editable={this.editable}></CommentList> <CommentList ref={(r) => this.commentList = r}
diaryId={diary.id}
editable={this.editable}
></CommentList>
</View> </View>
); );

View file

@ -91,6 +91,7 @@ export default class DiaryList extends Component {
}); });
} }
// to be seperated as diaryAction component
_onDiaryAction(diary) { _onDiaryAction(diary) {
ActionSheet.showActionSheetWithOptions({ ActionSheet.showActionSheetWithOptions({
options:['修改','删除', '取消'], options:['修改','删除', '取消'],
@ -99,7 +100,26 @@ export default class DiaryList extends Component {
}, (index) => { }, (index) => {
if(index === 0) { if(index === 0) {
Navigation.push(this.props.componentId, {
component: {
name: 'Write',
options: {
bottomTabs: {
visible: false,
// hide bottom tab for android
drawBehind: true,
animate: true
}
},
passProps: {
diary: diary,
onSave: (diary) => {
//
}
}
}
});
} else if (index === 1) { } else if (index === 1) {
Alert.alert('提示', '确认删除日记?', [ Alert.alert('提示', '确认删除日记?', [
@ -132,7 +152,6 @@ export default class DiaryList extends Component {
this.setState({refreshing: true, refreshFailed: false}); this.setState({refreshing: true, refreshFailed: false});
this.dataSource.refresh() this.dataSource.refresh()
.then(result => { .then(result => {
console.log('diary list result:', result);
if(!result) { if(!result) {
throw { throw {
message: 'refresh diary no result' message: 'refresh diary no result'
@ -208,7 +227,7 @@ export default class DiaryList extends Component {
data={this.state.diaries} data={this.state.diaries}
keyExtractor={(item, index) => { keyExtractor={(item, index) => {
return item.id.toString() + item.comment_count; return item.id + item.updated + item.comment_count;
}} }}
renderItem={({item}) => { renderItem={({item}) => {

View file

@ -25,8 +25,9 @@ export default class NotebookDiaryList extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.dataSource = new NotebookDiaryData(); this.editable = props.editable || false;
this.notebook = props.notebook; this.notebook = props.notebook;
this.dataSource = new NotebookDiaryData();
this.state = { this.state = {
diaries: [], diaries: [],
@ -164,7 +165,8 @@ export default class NotebookDiaryList extends Component {
} }
}, },
passProps: { passProps: {
diary: diary diary: diary,
editable: this.editable
} }
} }
}); });

View file

@ -19,36 +19,18 @@ export default class NotebookLine extends Component {
super(props); super(props);
this.state = { this.state = {
notebooks: [] notebooks: props.notebooks || []
}; };
} }
componentDidMount(){ componentDidMount() {
InteractionManager.runAfterInteractions(() => { notebooks = this.props.refreshData()
this.load();
});
}
load() { if(notebooks && notebooks.length > 0) {
Api.getSelfNotebooks() this.setState({
.then(notebooks => { 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() { render() {
@ -69,7 +51,7 @@ export default class NotebookLine extends Component {
this.state.notebooks.map((notebook) => { this.state.notebooks.map((notebook) => {
return ( return (
<TouchableOpacity key={notebook.id} activeOpacity={0.7} <TouchableOpacity key={notebook.id} activeOpacity={0.7}
onPress={this.props.onNotebookPress}> onPress={() => this.props.onNotebookPress(notebook)}>
<Notebook key={notebook.id} style={{paddingRight: 10}} <Notebook key={notebook.id} style={{paddingRight: 10}}
notebook={notebook} /> notebook={notebook} />

View file

@ -85,7 +85,8 @@ export default class NotebookList extends Component {
} }
}, },
passProps: { passProps: {
notebook: notebook notebook: notebook,
editable: !this.state.user
} }
} }
}); });

View file

@ -5,8 +5,10 @@ function config() {
return { return {
root: { root: {
bottomTabs: { bottomTabs: {
id: 'MainBottomTab',
options: { options: {
bottomTabs: { bottomTabs: {
currentTabIndex: 0,
titleDisplayMode: 'alwaysShow' // android titleDisplayMode: 'alwaysShow' // android
} }
}, },
@ -64,15 +66,13 @@ function config() {
stack: { stack: {
children: [{ children: [{
component: { component: {
name: 'Write', name: 'Empty',
options: { options: {
topBar: { topBar: {
title: { visible: false
text: '写日记',
alignment: 'center' // android
}
} }
} }
} }
}], }],
options: { options: {

View file

@ -1,11 +1,21 @@
import React, {Component} from 'react'; import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, ScrollView} from 'react-native'; import {
Platform,
StyleSheet,
Text,
View,
ScrollView,
DeviceEventEmitter,
Keyboard
} from 'react-native';
import {Navigation} from 'react-native-navigation'; import {Navigation} from 'react-native-navigation';
import KeyboardSpacer from "react-native-keyboard-spacer";
import Color from '../style/color'; import Color from '../style/color';
import {Icon} from '../style/icon'; import {Icon} from '../style/icon';
import Msg from '../util/msg'; import Msg from '../util/msg';
import Api from '../util/api' import Api from '../util/api'
import Event from '../util/event';
import DiaryFull from '../component/diary/diaryFull'; import DiaryFull from '../component/diary/diaryFull';
import CommentInput from '../component/comment/commentInput' import CommentInput from '../component/comment/commentInput'
@ -17,10 +27,16 @@ export default class DiaryDetailPage extends Component {
super(props); super(props);
Navigation.events().bindComponent(this); Navigation.events().bindComponent(this);
this.diary = props.diary; this.state = {
this.user = props.user; selfInfo: null,
diary: props.diary,
user: props.user,
editable: props.editable || false,
needScrollToBottom: false
}
this.editable = props.editable || false;
this.onDiaryAction = props.onDiaryAction || (() => {}); this.onDiaryAction = props.onDiaryAction || (() => {});
} }
@ -41,8 +57,8 @@ export default class DiaryDetailPage extends Component {
} }
navigationButtonPressed({buttonId}) { navigationButtonPressed({buttonId}) {
if(this.editable) { if(this.state.editable) {
this.onDiaryAction(); this.onDiaryAction(this.state.diary);
} else { } else {
ActionSheet.showActionSheetWithOptions({ ActionSheet.showActionSheetWithOptions({
@ -52,22 +68,65 @@ export default class DiaryDetailPage extends Component {
}, (index) => { }, (index) => {
if(index == 0) { if(index == 0) {
// Api.report(this.diary.user_id, this.diary.id).done(); Api.report(this.state.diary.user_id, this.state.diary.id).done();
Msg.showMsg('举报成功,感谢你的贡献 :)'); Msg.showMsg('举报成功,感谢你的贡献 :)');
} }
}); });
} }
} }
componentDidMount() {
Api.getSelfInfoByStore()
.then(user => {
this.setState({
selfInfo: user
});
}).done();
this.listener = DeviceEventEmitter.addListener(Event.updateComments, (param) => {
this.setState({needScrollToBottom: true});
this.diaryFull.refreshComment();
Keyboard.dismiss();
});
}
componentWillUnmount(){
this.listener.remove();
}
render() { render() {
return ( return (
<View style={localStyle.wrap}> <View style={localStyle.wrap}>
<ScrollView style={{flex: 1}}> <ScrollView ref={(r)=>this.scroll = r}
<DiaryFull diary={this.props.diary} editable={this.editable}></DiaryFull> style={{flex: 1}}
onContentSizeChange={(width, height) => {
if(this.state.needScrollToBottom) {
this.scroll.scrollTo({y: height});
this.setState({needScrollToBottom: false});
}
}}
>
<DiaryFull ref={(r) => this.diaryFull = r}
diary={this.state.diary}
editable={this.state.editable}
></DiaryFull>
</ScrollView> </ScrollView>
<CommentInput></CommentInput> {
this.state.selfInfo ? (
<CommentInput ref={(r) => this.commentInput = r}
diary={this.state.diary}
selfInfo={this.state.selfInfo}
></CommentInput>
) : null
}
{
Api.IS_IOS ? <KeyboardSpacer topSpacing={Api.IS_IPHONEX ? -30 : 0} /> : null
}
</View> </View>
); );
} }

74
src/page/EmptyPage.js Normal file
View file

@ -0,0 +1,74 @@
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, Alert} from 'react-native';
import {Navigation} from 'react-native-navigation';
export default class EmptyPage extends Component {
constructor(props) {
super(props);
this.state = {
from: props.from
}
}
componentDidMount() {
this.navigationEventListener = Navigation.events().bindComponent(this);
}
componentWillUnmount() {
this.navigationEventListener.remove();
}
componentDidAppear() {
let forword = true;
if(this.state.from == 'write') {
forword = false;
this.setState({from: ''});
}
if(!forword) {
Navigation.mergeOptions(this.props.componentId, {
bottomTabs: {
currentTabIndex: 4
}
});
} else {
Navigation.push(this.props.componentId, {
component: {
name: 'Write',
options: {
animations: {
push: {
enabled: false
},
pop: {
enabled: false
}
},
bottomTabs: {
visible: false,
// hide bottom tab for android
drawBehind: true,
animate: true
}
},
passProps: {
}
}
});
}
}
render() {
return null;
}
}

View file

@ -15,18 +15,23 @@ export default class NotebookDetailPage extends Component {
} }
static options(passProps) { static options(passProps) {
return { let topBar = {
topBar: { title: {
title: { text: '《' + passProps.notebook.subject + '》'
text: '《' + passProps.notebook.subject + '》'
},
rightButtons: [{
id: 'navButtonNotebookSetting',
icon: Icon.navButtonNotebookSetting,
color: Color.primary
}]
} }
}
if(passProps.editable) {
topBar.rightButtons = [{
id: 'navButtonNotebookSetting',
icon: Icon.navButtonNotebookSetting,
color: Color.primary
}];
}
return {
topBar
}; };
} }

View file

@ -1,7 +1,7 @@
import React, {Component} from 'react'; import React, {Component} from 'react';
import {StyleSheet, Text, View, Animated, DeviceEventEmitter, Alert} from 'react-native'; import {StyleSheet, Text, View, Animated, DeviceEventEmitter, Alert} from 'react-native';
import { import {
PagerScroll, PagerPan,
TabView, TabView,
TabBar, TabBar,
SceneMap SceneMap
@ -30,7 +30,7 @@ export default class UserPage extends Component {
this.dataSource = new UserDiaryData(this.userId); this.dataSource = new UserDiaryData(this.userId);
this.state = { this.state = {
index: 0, index: 1,
routes: [ routes: [
{ key: 'userIntro', title: '简介' }, { key: 'userIntro', title: '简介' },
{ key: 'diary', title: '日记' }, { key: 'diary', title: '日记' },
@ -104,7 +104,7 @@ export default class UserPage extends Component {
} }
} }
componentDidMount(){ componentDidMount() {
if(this.userId) { if(this.userId) {
Api.getRelation(this.userId) Api.getRelation(this.userId)
.then(re => { .then(re => {
@ -120,15 +120,21 @@ export default class UserPage extends Component {
}); });
} }
}); });
} }
this.listener = DeviceEventEmitter.addListener(Event.updateNotebooks, (param) => { this.notebookListener = DeviceEventEmitter.addListener(Event.updateNotebooks, (param) => {
this.notebookList.refresh(); this.notebookList.refresh();
}); });
this.diaryListener = DeviceEventEmitter.addListener(Event.updateDiarys, (param) => {
this.diaryList.refresh();
});
} }
componentWillUnmount(){ componentWillUnmount() {
this.listener.remove(); this.notebookListener.remove();
this.diaryListener.remove();
} }
_renderLabel = props => ({route}) => { _renderLabel = props => ({route}) => {
@ -163,6 +169,7 @@ export default class UserPage extends Component {
user={this.user} user={this.user}
/>, />,
diary: () => <DiaryList diary: () => <DiaryList
ref={(r) => this.diaryList = r}
dataSource={this.dataSource} dataSource={this.dataSource}
editable={!this.user} editable={!this.user}
{...this.props} {...this.props}
@ -182,7 +189,7 @@ export default class UserPage extends Component {
width: Api.DEVICE_WINDOW.width width: Api.DEVICE_WINDOW.width
}} }}
renderPager={(props) => <PagerScroll {...props}/>} /* android */ renderPager = {props => <PagerPan {...props} />} /* android */
renderTabBar={this._renderTabBar} renderTabBar={this._renderTabBar}
renderScene={this._renderScene} renderScene={this._renderScene}

View file

@ -9,16 +9,23 @@ import {
Modal, Modal,
Animated, Animated,
Easing, Easing,
TouchableWithoutFeedback TouchableWithoutFeedback,
DeviceEventEmitter,
Alert
} from 'react-native'; } from 'react-native';
import {Navigation} from 'react-native-navigation'; import {Navigation} from 'react-native-navigation';
import KeyboardSpacer from "react-native-keyboard-spacer";
import Ionicons from 'react-native-vector-icons/Ionicons'; import Ionicons from 'react-native-vector-icons/Ionicons';
import {Icon} from '../style/icon' import BottomNav from '../nav/bottomNav';
import Color from '../style/color' import {Icon} from '../style/icon';
import Api from '../util/api' import Color from '../style/color';
import Api from '../util/api';
import Msg from '../util/msg';
import Token from '../util/token'
import Event from "../util/event";
import NotebookLine from '../component/notebook/notebookLine' import NotebookLine from '../component/notebook/notebookLine';
export default class WritePage extends Component { export default class WritePage extends Component {
@ -27,8 +34,14 @@ export default class WritePage extends Component {
super(props); super(props);
Navigation.events().bindComponent(this); Navigation.events().bindComponent(this);
let diary = this.diary = props.diary;
this.state = { this.state = {
content: '', notebooks: [],
targetbookId: diary ? diary.notebook_id : 0,
targetbookSubject: diary ? diary.notebook_subject : '',
content: diary ? diary.content : '',
modalVisible: false, modalVisible: false,
fadeAnimOpacity: new Animated.Value(0), fadeAnimOpacity: new Animated.Value(0),
@ -50,19 +63,57 @@ export default class WritePage extends Component {
id: 'save', id: 'save',
icon: Icon.navButtonSave icon: Icon.navButtonSave
}] }]
},
bottomTabs: {
visible: false,
// hide bottom tab for android
drawBehind: true,
animate: true
} }
}; };
} }
navigationButtonPressed({buttonId}) {
if(buttonId == 'cancel') {
if(this.diary) {
Navigation.pop(this.props.componentId);
} else {
Navigation.setStackRoot(this.props.componentId, {
component: {
name: 'Empty',
options: {
bottomTabs: {
visible: true
}
},
passProps: {
from: 'write'
}
}
});
}
} else if(buttonId == 'save') {
this.saveDiary();
}
}
componentDidMount() {
this.loadNotebook();
this.notebookListener = DeviceEventEmitter.addListener(Event.updateNotebooks, (param) => {
this.loadNotebook(true);
});
}
componentWillUnmount(){
this.notebookListener.remove();
}
openModal() { openModal() {
this.setState({modalVisible: true}); this.setState({modalVisible: true});
if(this.state.notebooks.length == 0) {
Alert.alert('提示', '没有可用日记本,无法写日记', [
{text: '确定', onPress: () => {}}
]);
}
} }
closeModal(showKeyboard = true) { closeModal(showKeyboard = true) {
@ -95,6 +146,88 @@ export default class WritePage extends Component {
}); });
} }
_onCreateNotebook() {
this.closeModal(false);
Navigation.push(this.props.componentId, {
component: {
name: 'NotebookEdit'
}
});
}
_onNotebookSelected(notebook) {
this.setState({
targetbookId: notebook.id,
targetbookSubject: notebook.subject
}, () => {
this.closeModal();
});
}
loadNotebook(resetTargetbook = false) {
Api.getSelfNotebooks()
.then(notebooks => {
if(!notebooks || !notebooks.filter) {
notebooks = [];
}
let unExpiredBooks = notebooks.filter(it => !it.isExpired);
if(unExpiredBooks.length > 0) {
let st = {
notebooks: unExpiredBooks
}
if(resetTargetbook || this.state.targetbookId == 0) {
st.targetbookId = unExpiredBooks[0].id;
st.targetbookSubject = unExpiredBooks[0].subject;
}
this.setState(st);
}
}).done();
}
saveDiary() {
let photoUri = null;
let topic = this.props.topic ? 1 : 0;
(this.diary
? Api.updateDiary(this.diary.id, this.state.targetbookId, this.state.content)
: Api.addDiary(this.state.targetbookId, this.state.content, null, topic)
).then(result => {
Msg.showMsg('日记保存完成');
DeviceEventEmitter.emit(Event.updateDiarys);
this.props.onSave(result);
if(this.diary) {
Navigation.pop(this.props.componentId);
} else {
Navigation.setStackRoot(this.props.componentId, {
component: {
name: 'Empty',
options: {
bottomTabs: {
visible: true
}
},
passProps: {
from: 'write'
}
}
});
}
})
.catch(e => {
Msg.showMsg('保存失败');
})
.done();
}
render() { render() {
return ( return (
<ScrollView style={localStyle.container} <ScrollView style={localStyle.container}
@ -112,7 +245,9 @@ export default class WritePage extends Component {
placeholder='记录点滴生活' placeholder='记录点滴生活'
value={this.state.content} value={this.state.content}
onChangeText={() => {}} onChangeText={(text) => {
this.setState({content: text});
}}
autoCorrect={false} autoCorrect={false}
autoCapitalize='none' autoCapitalize='none'
@ -123,22 +258,24 @@ export default class WritePage extends Component {
<View style={localStyle.notebookButton}> <View style={localStyle.notebookButton}>
<Ionicons name='ios-bookmarks-outline' size={16} <Ionicons name='ios-bookmarks-outline' size={16}
color={Color.text} style={{marginTop: 2, marginRight: 6}} /> color={Color.text} style={{marginTop: 2, marginRight: 6}} />
<Text style={{fontSize: 13, color: Color.text }}>{'日记本名'}</Text> <Text style={{fontSize: 13, color: Color.text }}>
{this.state.targetbookSubject ? this.state.targetbookSubject : '..'}
</Text>
</View> </View>
</TouchableOpacity> </TouchableOpacity>
<View style={{flex: 1}} /> <View style={{flex: 1}} />
<TouchableOpacity>
<Text style={localStyle.topic}># {'话题名'}</Text>
</TouchableOpacity>
<TouchableOpacity style={localStyle.photo} onPress={() => {}}> <TouchableOpacity style={localStyle.photo} onPress={() => {}}>
<Ionicons name="ios-image-outline" size={30} <Ionicons name="ios-image-outline" size={30}
style={{paddingTop: 4}} color={Color.light} /> style={{paddingTop: 4}} color={Color.light} />
</TouchableOpacity> </TouchableOpacity>
</View> </View>
{
Api.IS_IOS ? <KeyboardSpacer topSpacing={Api.IS_IPHONEX ? -30 : 0} /> : null
}
{this.renderModal()} {this.renderModal()}
</ScrollView> </ScrollView>
@ -180,7 +317,7 @@ export default class WritePage extends Component {
<Animated.View style={{height: this.state.fadeAnimHeight, backgroundColor: '#fff'}}> <Animated.View style={{height: this.state.fadeAnimHeight, backgroundColor: '#fff'}}>
<View style={localStyle.modalBanner}> <View style={localStyle.modalBanner}>
<TouchableOpacity onPress={() => {}} style={localStyle.modalButton}> <TouchableOpacity onPress={this._onCreateNotebook.bind(this)} style={localStyle.modalButton}>
<Text style={localStyle.modalButtonText}>新添</Text> <Text style={localStyle.modalButtonText}>新添</Text>
</TouchableOpacity> </TouchableOpacity>
<Text style={{padding: 10, color: Color.text}}>选择日记本</Text> <Text style={{padding: 10, color: Color.text}}>选择日记本</Text>
@ -189,7 +326,10 @@ export default class WritePage extends Component {
</TouchableOpacity> </TouchableOpacity>
</View> </View>
<NotebookLine onNotebookPress={() => {}}></NotebookLine> <NotebookLine
refreshData={() => this.state.notebooks}
onNotebookPress={this._onNotebookSelected.bind(this)}
></NotebookLine>
</Animated.View> </Animated.View>
</View> </View>
@ -259,6 +399,6 @@ const localStyle = StyleSheet.create({
}, },
modalButtonText: { modalButtonText: {
color: Color.light, color: Color.light,
fontSize: 15, fontSize: 15
} }
}); });

View file

@ -1,5 +1,6 @@
export default { export default {
DiaryDetail: require("./DiaryDetailPage.js").default, DiaryDetail: require("./DiaryDetailPage.js").default,
Empty: require("./EmptyPage.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,

View file

@ -89,13 +89,21 @@ async function getUserTodayDiaries(userId) {
} }
async function getDiaryComments(diaryId) { async function getDiaryComments(diaryId) {
return call('GET', '/diaries/' + diaryId + '/comments') return call('GET', '/diaries/' + diaryId + '/comments');
} }
async function deleteComment(id) { async function deleteComment(id) {
return call('DELETE', '/comments/' + id) return call('DELETE', '/comments/' + id);
} }
async function addComment(diaryId, content, recipient_id) {
return call('POST', '/diaries/' + diaryId + '/comments', {
content: content,
recipient_id: recipient_id,
});
}
async function getSelfNotebooks() { async function getSelfNotebooks() {
return call('GET', '/notebooks/my') return call('GET', '/notebooks/my')
} }
@ -169,6 +177,34 @@ async function deleteNotebook(id) {
return call('DELETE', '/notebooks/' + id) return call('DELETE', '/notebooks/' + id)
} }
async function addDiary(bookId, content, photoUri = null, join_topic = null) {
if(!photoUri) {
return call('POST', '/notebooks/' + bookId + '/diaries', {
content,
join_topic
});
} else {
return upload('POST', '/notebooks/' + bookId + '/diaries', {
content,
join_topic,
photo: {
uri: photoUri,
name: 'image.jpg',
type: 'image/jpg'
}
});
}
}
async function updateDiary(id, bookId, content) {
return call('PUT', '/diaries/' + id, {
content,
notebook_id: bookId
});
}
async function report(user_id, diary_id) { async function report(user_id, diary_id) {
return call('POST', '/reports/', { return call('POST', '/reports/', {
user_id: user_id, user_id: user_id,
@ -303,6 +339,7 @@ export default {
getDiaryComments, getDiaryComments,
deleteComment, deleteComment,
addComment,
getSelfNotebooks, getSelfNotebooks,
getUserNotebooks, getUserNotebooks,
@ -321,5 +358,8 @@ export default {
updateNotebook, updateNotebook,
deleteNotebook, deleteNotebook,
addDiary,
updateDiary,
report report
} }

View file

@ -1,4 +1,9 @@
export default { export default {
updateNotebooks: 'updateNotebooks'
updateNotebooks: 'updateNotebooks',
updateDiarys: 'updateDiarys',
updateComments: 'updateComments',
commentPressed: 'commentPressed'
} }