diff --git a/android/app/build.gradle b/android/app/build.gradle
index 700db09..cd91b28 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -152,7 +152,7 @@ dependencies {
implementation project(':react-native-navigation')
implementation fileTree(dir: "libs", include: ["*.jar"])
- implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
+ implementation 'androidx.appcompat:appcompat:1.0.0'
implementation "com.facebook.react:react-native:+" // From node_modules
}
diff --git a/android/gradle.properties b/android/gradle.properties
index 89e0d99..ccb748f 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -16,3 +16,6 @@
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
+
+android.useAndroidX=true
+android.enableJetifier=true
\ No newline at end of file
diff --git a/src/component/comment/comment.js b/src/component/comment/comment.js
index 5fdb75d..b037835 100644
--- a/src/component/comment/comment.js
+++ b/src/component/comment/comment.js
@@ -79,13 +79,15 @@ const localStyle = StyleSheet.create({
},
titleText: {
fontSize: 12,
- color: Color.inactiveText
+ color: Color.inactiveText,
+ paddingRight: 10
},
content: {
flexGrow: 1,
lineHeight: 26,
color: Color.text,
fontSize: 15,
+ paddingRight: 5,
marginBottom: 10
},
line: {
diff --git a/src/component/diary/diaryBrief.js b/src/component/diary/diaryBrief.js
index baad127..ed42f0c 100644
--- a/src/component/diary/diaryBrief.js
+++ b/src/component/diary/diaryBrief.js
@@ -3,6 +3,7 @@ import {StyleSheet, Text, View, TouchableOpacity} from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons';
import moment from 'moment';
+import Touchable from '../touchable';
import Color from '../../style/color';
import UserIcon from '../userIcon';
import Photo from '../photo';
@@ -17,8 +18,11 @@ export default class DiaryBrief extends Component {
constructor(props) {
super(props);
- this.diary = props.diary;
- this.diary.isExpired = props.isExpired || false;
+ this.state = {
+ diary: props.diary
+ }
+
+ this.expired = props.expired || false;
this.editable = props.editable || false;
this.showField = ['userIcon', 'userName', 'subject', 'createdTime'];
@@ -32,11 +36,17 @@ export default class DiaryBrief extends Component {
}
onDiaryAction() {
- DiaryAction.action(this.props.componentId, this.diary);
+ DiaryAction.action(this.props.componentId, this.state.diary);
+ }
+
+ refreshDiary(diary) {
+ if(diary && this.props.refreshBack) {
+ this.props.refreshBack(diary);
+ }
}
render() {
- let diary = this.diary;
+ let diary = this.state.diary;
if(!diary) {
return null;
}
@@ -44,6 +54,7 @@ export default class DiaryBrief extends Component {
let user = diary.user;
return (
+ this.props.onDiaryPress ? this.props.onDiaryPress(this.state.diary) : null}>
{(user && user.iconUrl && this.show('userIcon'))
? : null}
@@ -80,7 +91,9 @@ export default class DiaryBrief extends Component {
+ clickable={!this.expired}
+ refreshBack={this.refreshDiary.bind(this)}
+ >
{
@@ -96,6 +109,7 @@ export default class DiaryBrief extends Component {
+
);
}
}
diff --git a/src/component/diary/diaryFull.js b/src/component/diary/diaryFull.js
index 1641ec7..a917ae8 100644
--- a/src/component/diary/diaryFull.js
+++ b/src/component/diary/diaryFull.js
@@ -8,6 +8,7 @@ import UserIcon from '../userIcon';
import Photo from '../photo';
import CommentList from '../comment/commentList';
+import DiaryIconOkB from './diaryIconOkB';
export default class DiaryFull extends Component {
@@ -17,16 +18,12 @@ export default class DiaryFull extends Component {
this.state = {
diary: props.diary,
- editable: props.editable || false
+ editable: props.editable || false,
+ expired: props.expired || false
}
}
- refreshDiaryContent() {
- if(!this.props.refreshData) {
- return;
- }
-
- let diary = this.props.refreshData();
+ refreshDiaryContent(diary) {
if(diary) {
this.setState({diary})
}
@@ -103,6 +100,14 @@ export default class DiaryFull extends Component {
this._onPhotoPress(diary.photoUrl)}>
+
+
+
+
@@ -125,7 +130,7 @@ const localStyle = StyleSheet.create({
overflow: "hidden",
paddingHorizontal: 15,
paddingTop: 15,
- marginBottom: 30
+ marginBottom: 1
},
body: {
flexDirection: "column",
@@ -137,6 +142,7 @@ const localStyle = StyleSheet.create({
title: {
flexDirection: "row",
alignItems: "flex-end",
+ paddingRight: 10,
paddingBottom: 5
},
titleName: {
@@ -153,6 +159,14 @@ const localStyle = StyleSheet.create({
lineHeight: 24,
color: Color.text,
fontSize: 15,
+ paddingRight: 5,
textAlignVertical: 'bottom'
+ },
+ actionBar: {
+ flexDirection: 'row',
+ width: '100%',
+ height: 30,
+ marginTop: 15,
+ justifyContent: 'flex-end'
}
});
diff --git a/src/component/diary/diaryIconOkB.js b/src/component/diary/diaryIconOkB.js
index 8b3a6c1..5856fc1 100644
--- a/src/component/diary/diaryIconOkB.js
+++ b/src/component/diary/diaryIconOkB.js
@@ -1,9 +1,17 @@
import React, {Component} from 'react';
-import {StyleSheet, Text, View, Image, TouchableOpacity} from 'react-native';
+import {
+ StyleSheet,
+ Text,
+ View,
+ Image,
+ TouchableOpacity,
+ DeviceEventEmitter
+} from 'react-native';
import Color from '../../style/color';
import Api from '../../util/api';
import Msg from '../../util/msg';
+import Event from '../../util/event';
export default class DiaryIconOkB extends Component {
@@ -17,6 +25,19 @@ export default class DiaryIconOkB extends Component {
active: props.active || false,
clickable: props.clickable && true
}
+
+ this.refreshBack = props.refreshBack || null;
+ }
+
+ componentWillReceiveProps(nextProps) {
+ this.setState({
+ diaryId: nextProps.diaryId || null,
+ count: nextProps.count || 0,
+ active: nextProps.active || false,
+ clickable: nextProps.clickable && true
+ });
+
+ this.refreshBack = nextProps.refreshBack || null;
}
onPress() {
@@ -27,32 +48,25 @@ export default class DiaryIconOkB extends Component {
let count = this.state.count;
let isActive = this.state.active;
- if(!isActive) {
- Api.likeDiary(this.state.diaryId)
- .then(re => {
- this.setState({
- count: count + 1,
- active: true
+ (!isActive ? Api.likeDiary(this.state.diaryId) : Api.cancelLikeDiary(this.state.diaryId))
+ .then(re => {
+ if(this.refreshBack) {
+ Api.getDiary(this.state.diaryId)
+ .then(result => {
+ if(result) {
+ this.refreshBack(result);
+ }
})
- })
- .catch(e => {
- Msg.showMsg('操作失败');
- })
- .done();
+ .done();
- } else {
- Api.cancelLikeDiary(this.state.diaryId)
- .then(re => {
- this.setState({
- count: count - 1,
- active: false
- })
- })
- .catch(e => {
- Msg.showMsg('操作失败');
- })
- .done();
- }
+ } else {
+ DeviceEventEmitter.emit(Event.updateDiarys);
+ }
+ })
+ .catch(e => {
+ Msg.showMsg('操作失败');
+ })
+ .done();
}
render() {
@@ -82,8 +96,7 @@ export default class DiaryIconOkB extends Component {
const localStyle = StyleSheet.create({
wrap: {
- flexDirection: 'row',
- marginRight: 6
+ flexDirection: 'row'
},
icon: {
width: 18,
diff --git a/src/component/diary/diaryList.js b/src/component/diary/diaryList.js
index 6a5710b..e6a246a 100644
--- a/src/component/diary/diaryList.js
+++ b/src/component/diary/diaryList.js
@@ -52,6 +52,12 @@ export default class DiaryList extends Component {
});
}
+ scrollToTop() {
+ this.list.scrollToOffset({
+ offset: 0
+ });
+ }
+
_onUserIconPress(diary) {
Navigation.push(this.props.componentId, {
component: {
@@ -72,7 +78,7 @@ export default class DiaryList extends Component {
});
}
- _onDiaryPress(diary) {
+ _onDiaryPress(index, diary) {
Navigation.push(this.props.componentId, {
component: {
name: 'DiaryDetail',
@@ -89,7 +95,8 @@ export default class DiaryList extends Component {
diary: diary,
user: diary.user,
- editable: this.editable
+ editable: this.editable,
+ refreshBack: this.refreshOne.bind(this, index)
}
}
});
@@ -106,6 +113,18 @@ export default class DiaryList extends Component {
});
}
+ refreshOne(index, diary) {
+ if(diary) {
+ let list = this.state.diaries;
+ diary.user = list[index].user;
+ list[index] = diary;
+
+ this.setState({
+ diaries: list
+ });
+ }
+ }
+
async refresh() {
if(this.state.refreshing) {
return;
@@ -195,7 +214,7 @@ export default class DiaryList extends Component {
return (
- this.list = r} style={localStyle.list}
data={this.state.diaries}
@@ -203,20 +222,20 @@ export default class DiaryList extends Component {
return item.id + item.updated + item.comment_count + item.like_count;
}}
- renderItem={({item}) => {
+ renderItem={({item, index}) => {
return (
- this._onDiaryPress(item)}>
- this._onUserIconPress(item)}
- onPhotoPress={() => this._onPhotoPress(item.photoUrl)}
- >
+ onDiaryPress={this._onDiaryPress.bind(this, index)}
+ onUserIconPress={() => this._onUserIconPress(item)}
+ onPhotoPress={() => this._onPhotoPress(item.photoUrl)}
-
-
+ refreshBack={this.refreshOne.bind(this, index)}
+ >
+
)
}}
diff --git a/src/component/notebook/notebookDiaryList.js b/src/component/notebook/notebookDiaryList.js
index 4e86401..dccf81d 100644
--- a/src/component/notebook/notebookDiaryList.js
+++ b/src/component/notebook/notebookDiaryList.js
@@ -29,11 +29,12 @@ export default class NotebookDiaryList extends Component {
constructor(props) {
super(props);
- this.editable = props.editable || false;
this.notebook = props.notebook;
+ this.editable = props.editable || false;
this.dataSource = new NotebookDiaryData();
this.state = {
+ rawlist: [],
diaries: [],
refreshing: false,
@@ -84,6 +85,19 @@ export default class NotebookDiaryList extends Component {
return result;
}
+ refreshOne(index, diary) {
+ console.log('index, diary:', index, diary);
+ if(diary) {
+ let list = this.state.rawlist;
+ diary.user = list[index].user;
+ list[index] = diary;
+
+ this.setState({
+ diaries: this.formatDiaries(list)
+ });
+ }
+ }
+
refresh() {
if (this.state.refreshing) {
return;
@@ -100,6 +114,8 @@ export default class NotebookDiaryList extends Component {
} else {
let diaries = this.formatDiaries(result.list);
this.setState({
+ rawlist: result.list,
+
diaries,
hasMore: result.more,
refreshFailed: false
@@ -134,6 +150,8 @@ export default class NotebookDiaryList extends Component {
} else {
let diaries = this.formatDiaries(result.list);
this.setState({
+ rawlist: result.list,
+
diaries,
hasMore: result.more,
loadFailed: false
@@ -153,7 +171,7 @@ export default class NotebookDiaryList extends Component {
});
}
- _onDiaryPress(diary) {
+ _onDiaryPress(index, diary) {
Navigation.push(this.props.componentId, {
component: {
name: 'DiaryDetail',
@@ -169,7 +187,9 @@ export default class NotebookDiaryList extends Component {
passProps: {
diary: diary,
editable: this.editable,
- expired: this.notebook.isExpired
+ expired: this.notebook.isExpired,
+
+ refreshBack: this.refreshOne.bind(this, index)
}
}
});
@@ -180,23 +200,31 @@ export default class NotebookDiaryList extends Component {
return null;
}
- let isExpired = this.notebook.isExpired;
+ let expired = this.notebook.isExpired;
return (
item.id}
+ keyExtractor={(item, index) => {
+ return item.id + item.updated + item.comment_count + item.like_count;
+ }}
sections={this.state.diaries}
renderItem={(rowData) => {
- return ( this._onDiaryPress(rowData.item)}>
-
- }
+ return (
+
- );
+ );
}}
renderSectionHeader={(info) => {
diff --git a/src/component/userIntro.js b/src/component/userIntro.js
index 4784a59..9a612b2 100644
--- a/src/component/userIntro.js
+++ b/src/component/userIntro.js
@@ -52,28 +52,29 @@ export default class UserIntro extends Component {
}
render() {
+ if(this.state.isLoading) {
+ return ;
+ }
+
const user = this.state.user;
+ return user ? (
+
+
+
+ {user.name}
+
- return this.state.isLoading
- ?
- : (
-
-
-
- {user.name}
-
+ {
+ user.intro && user.intro.length > 0
+ ? ({user.intro}) : null
+ }
+
+
+ {moment(user.created).format('YYYY年M月D日')}加入胶囊
+
- {
- user.intro && user.intro.length > 0
- ? ({user.intro}) : null
- }
-
-
- {moment(user.created).format('YYYY年M月D日')}加入胶囊
-
-
-
- );
+
+ ) : null;
}
}
diff --git a/src/page/DiaryDetailPage.js b/src/page/DiaryDetailPage.js
index 72553e1..572d50d 100644
--- a/src/page/DiaryDetailPage.js
+++ b/src/page/DiaryDetailPage.js
@@ -131,15 +131,10 @@ export default class DiaryDetailPage extends Component {
}
}
- this.setState({
- diary: result
- }, () => {
- this.diaryFull.refreshDiaryContent();
- })
+ this.props.refreshBack(result);
+ this.diaryFull.refreshDiaryContent(result);
})
- .done(() => {
-
- });
+ .done();
}
render() {
@@ -167,8 +162,8 @@ export default class DiaryDetailPage extends Component {
this.diaryFull = r}
{...this.props}
diary={this.state.diary}
- refreshData={() => this.state.diary}
editable={this.state.editable || isMine}
+ expired={this.state.expired}
>
diff --git a/src/page/HomePage.js b/src/page/HomePage.js
index 6c18b73..b8491f1 100644
--- a/src/page/HomePage.js
+++ b/src/page/HomePage.js
@@ -16,6 +16,7 @@ import ActionSheet from 'react-native-actionsheet-api';
import Color from '../style/color'
import Api from '../util/api';
+import Update from '../util/update';
import DiaryList from '../component/diary/diaryList'
import HomeDiaryData from '../dataLoader/homeDiaryData';
@@ -49,6 +50,24 @@ export default class HomePage extends Component {
} else {
this.closeSplash();
}
+
+ this.bottomTabEventListener = Navigation.events().registerBottomTabSelectedListener(
+ ({ selectedTabIndex, unselectedTabIndex }) => {
+ if(selectedTabIndex == unselectedTabIndex && selectedTabIndex == 0) {
+ this.diaryList.scrollToTop();
+ }
+ }
+ );
+
+ if(Api.IS_ANDROID) {
+ setTimeout(() => {
+ Update.updateAndroid();
+ }, 2000);
+ }
+ }
+
+ componentWillUnmount() {
+ this.bottomTabEventListener.remove();
}
startTimer() {
@@ -189,7 +208,7 @@ export default class HomePage extends Component {
{
this.state.showSplash ? this.renderModal() : (
- this.list = r}
+ this.diaryList = r}
dataSource={this.dataSource}
listHeader={this.renderHeader.bind(this)}
refreshHeader={this.refreshTopic.bind(this)}
diff --git a/src/page/UserPage.js b/src/page/UserPage.js
index caa45c2..582d8e4 100644
--- a/src/page/UserPage.js
+++ b/src/page/UserPage.js
@@ -193,6 +193,7 @@ export default class UserPage extends Component {
diary: () => this.diaryList = r}
dataSource={this.dataSource}
+ showField={['subject', 'createdTime']}
editable={!this.user}
{...this.props}
/>,
diff --git a/src/util/api.js b/src/util/api.js
index 2103045..1b75aa2 100644
--- a/src/util/api.js
+++ b/src/util/api.js
@@ -339,6 +339,10 @@ async function feedback(content) {
return callV2('POST', '/feedback', {content});
}
+async function getUpdateInfo() {
+ return callV2('GET', '/updateInfo');
+}
+
async function upload(method, api, body) {
let token = await Token.getUserToken();
@@ -529,5 +533,6 @@ export default {
deleteNotebook,
report,
- feedback
+ feedback,
+ getUpdateInfo
}
\ No newline at end of file
diff --git a/src/util/update.js b/src/util/update.js
new file mode 100644
index 0000000..9be9e93
--- /dev/null
+++ b/src/util/update.js
@@ -0,0 +1,37 @@
+import React, {Component} from 'react';
+import {
+ Alert,
+ Linking
+} from 'react-native';
+
+import Api from './api';
+import Msg from './msg';
+
+
+async function updateAndroid() {
+ try {
+ let info = await Api.getUpdateInfo();
+ // console.log('update info:', info, Api.VERSION);
+ if(info.lastestVersion > Api.VERSION) {
+ Alert.alert(
+ '发现新版本 v' + info.lastestVersion,
+ info.message,
+ [
+ {text: '以后再说', onPress: () => {}},
+ {text: '更新', onPress: () => downloadApk(info.apkUrl, info.lastestVersion)},
+ ],
+ {cancelable: false}
+ )
+ }
+ } catch(e) {}
+}
+
+async function downloadApk(url, version) {
+ Linking.openURL(url);
+ Msg.showMsg('从浏览器下载更新包');
+}
+
+export default {
+ updateAndroid,
+ downloadApk
+}
\ No newline at end of file