Merge remote-tracking branch 'origin/master'

This commit is contained in:
li.zhaoguang 2020-01-04 16:25:53 +08:00
commit d169cf348a
7 changed files with 143 additions and 63 deletions

View file

@ -2,21 +2,11 @@ import React, {Component} from 'react';
import {Image, StyleSheet, Text, View, TouchableOpacity} from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons';
import UserIcon from '../userIcon';
import Touchable from '../touchable';
import Color from '../../style/color';
function unique(array) {
let n = [];
for(let i=0; i<array.length; i++) {
if(n.indexOf(array[i]) == -1) {
n.push(array[i])
};
}
return n;
}
export default class Notification extends Component {
_onDeletePress(msg) {
@ -28,7 +18,6 @@ export default class Notification extends Component {
if(msg && msg.type) {
if(msg.type == 1) {
return this.renderComment(msg);
} else if(msg.type == 2) {
return this.renderFollow(msg);
} else if(msg.type == 3) {
@ -48,14 +37,43 @@ export default class Notification extends Component {
}
renderComment(msg) {
const users = unique(msg.list.map(it => it.content.author.name)).join('、');
const body = `${users} 回复了你`;
const max = 5;
const formatMsg = {};
let key = null;
for (let i=0; i<msg.list.length; i++) {
key = msg.list[i].link_user_id;
if (!formatMsg[key]) {
formatMsg[key] = {
userId: msg.list[i].content.author.id,
userIcon: msg.list[i].link_user_icon,
userName: msg.list[i].content.author.name,
};
}
}
return (
<Touchable key={msg.link_id} onPress={() => this.props.onCommentPress(msg)}>
<View style={localStyle.container}>
<Ionicons name="ios-text" size={16} style={localStyle.icon} color={Color.light} />
<Text style={localStyle.text}>{body}</Text>
{
Object.keys(formatMsg).map((it, index) => {
if (index >= max) {
return null;
}
return (
<UserIcon key={formatMsg[it].userId || index}
iconUrl={formatMsg[it].userIcon}
width={24} height={24}
onPress={() => this.props.onUserIconPress(formatMsg[it])}
/>
);
})
}
<Text style={localStyle.text}>
{Object.keys(formatMsg).length > max ? '等' : ''}回复了你
</Text>
{this.renderDeleteButton(msg)}
</View>
</Touchable>
@ -63,13 +81,17 @@ export default class Notification extends Component {
}
renderFollow(msg) {
const body = `${msg.content.user.name} 关注了你`;
const userIcon = msg.link_user_icon;
return (
<Touchable key={msg.link_id} onPress={() => this.props.onFollowPress(msg)}>
<View style={localStyle.container}>
<Ionicons name="ios-heart" size={16} style={localStyle.icon} color='#d9534f' />
<Text key={msg.link_id} style={localStyle.text}>{body}</Text>
<Ionicons name="ios-heart" size={14} style={localStyle.icon} color='#d9534f' />
<UserIcon
iconUrl={userIcon}
width={24} height={24}
/>
<Text style={localStyle.text}>关注了你</Text>
{this.renderDeleteButton(msg)}
</View>
</Touchable>
@ -77,7 +99,11 @@ export default class Notification extends Component {
}
renderLike(msg) {
const body = `${msg.content.user.name} 给了你一个OK绷`;
const userData = {
userId: msg.content.user.id,
userIcon: msg.link_user_icon,
userName: msg.content.user.name,
}
return (
<Touchable key={msg.link_id} onPress={() => this.props.onLikePress(msg)}>
@ -89,7 +115,12 @@ export default class Notification extends Component {
}
style={localStyle.icon2}
/>
<Text style={localStyle.text}>{body}</Text>
<UserIcon
iconUrl={userData.userIcon}
width={24} height={24}
onPress={() => this.props.onUserIconPress(userData)}
/>
<Text style={localStyle.text}>给了你一个OK绷</Text>
{this.renderDeleteButton(msg)}
</View>
</Touchable>
@ -109,17 +140,18 @@ const localStyle = StyleSheet.create({
icon: {
marginRight: 10,
marginTop: 1,
lineHeight: 20
lineHeight: 28
},
text: {
flex: 1,
lineHeight: 20
lineHeight: 28
},
icon2: {
width: 15,
height: 15,
marginRight: 10,
marginTop: 4,
marginLeft: -1,
marginRight: 9,
marginTop: 7,
},
delete: {
lineHeight: 20,

View file

@ -34,6 +34,7 @@ export default class NotificationList extends Component {
(async () => {
try {
let notifications = await this.getMessages();
this.notificationsData = notifications;
this.setNotifications(notifications);
this.setState({error: false});
@ -106,6 +107,29 @@ export default class NotificationList extends Component {
}
}
_onUserIconPress(msg) {
Navigation.push(this.props.componentId, {
component: {
name: 'User',
options: {
bottomTabs: {
visible: false,
// hide bottom tab for android
drawBehind: true,
animate: true
}
},
passProps: {
user: {
id: msg.userId,
name: msg.userName,
}
}
}
});
}
_onCommentPress(msg) {
Navigation.push(this.props.componentId, {
component: {
@ -159,7 +183,7 @@ export default class NotificationList extends Component {
_onLikePress(msg) {
Navigation.push(this.props.componentId, {
component: {
name: 'User',
name: 'DiaryDetail',
options: {
bottomTabs: {
visible: false,
@ -170,7 +194,7 @@ export default class NotificationList extends Component {
}
},
passProps: {
user: msg.content.user
diaryId: msg.content.dairy_id
}
}
});
@ -199,6 +223,7 @@ export default class NotificationList extends Component {
renderItem={({item}) => {
return (
<Notification msg={item}
onUserIconPress={this._onUserIconPress.bind(this)}
onCommentPress={this._onCommentPress.bind(this)}
onFollowPress={this._onFollowPress.bind(this)}
onLikePress={this._onLikePress.bind(this)}
@ -230,16 +255,7 @@ export default class NotificationList extends Component {
}
}
// NotificationList.propTypes = {
// isHistory: PropTypes.boolean,
// onRefresh: PropTypes.func,
// isSetRead: PropTypes.boolean
// };
//
// NotificationList.defaultProps = {
// isHistory: true,
// isSetRead: false,
// };

View file

@ -24,8 +24,7 @@ export default class UserIcon extends Component {
render() {
return (
<Avatar rounded
containerStyle={localStyle.container}
<Avatar rounded containerStyle={localStyle.container}
width={this.props.width || 40}
height={this.props.height || 40}
source={{uri: this.state.iconUrl}}

View file

@ -40,15 +40,6 @@ export default class NotificationPage extends Component {
constructor(props) {
super(props);
Navigation.events().bindComponent(this);
// const ds = new ListView.DataSource({
// rowHasChanged: (r1, r2) => r1 !== r2
// });
// this.state = ({
// messages: [],
// messagesDataSource: ds,
// refreshing: true,
// });
}
navigationButtonPressed({buttonId}) {

View file

@ -132,6 +132,18 @@ export default class UserPage extends Component {
componentDidMount() {
if(this.userId) {
Api.getSelfInfoByStore()
.then(user => {
if(user && user.id == this.userId) {
Navigation.mergeOptions(this.props.componentId, {
topBar: {
rightButtons: [{
id: 'setting',
icon: Icon.navButtonSetting
}]
}
});
} else {
Api.getRelation(this.userId)
.then(re => {
this.followed = re;
@ -146,7 +158,8 @@ export default class UserPage extends Component {
});
}
});
}
});
}
this.notebookListener = DeviceEventEmitter.addListener(Event.updateNotebooks, (param) => {

View file

@ -24,7 +24,8 @@ import {Icon} from '../style/icon';
import Color from '../style/color';
import Api from '../util/api';
import Msg from '../util/msg';
import Event from "../util/event";
import Event from '../util/event';
import Token from '../util/token';
import NotebookLine from '../component/notebook/notebookLine';
import ImageAction from '../component/image/imageAction'
@ -54,6 +55,8 @@ export default class WritePage extends Component {
fadeAnimOpacity: new Animated.Value(0),
fadeAnimHeight: new Animated.Value(0)
}
this.draftTimer = null;
}
static options(passProps) {
@ -102,6 +105,9 @@ export default class WritePage extends Component {
}
closePage() {
clearInterval(this.draftTimer);
Token.setDraft('');
this.contentInput.blur();
if (this.diary || this.topic) {
Navigation.pop(this.props.componentId);
@ -112,10 +118,20 @@ export default class WritePage extends Component {
}
componentDidMount() {
Token.getDraft().then(draft => {
if(draft) {
this.setState({
content: draft,
});
}
});
this.resetDraftTimer();
this.loadNotebook().then(notebookCount => {
if(notebookCount > 0) {
InteractionManager.runAfterInteractions(() => {
this && this.contentInput && this.contentInput.focus();
this.contentInput && this.contentInput.focus();
});
} else {
Alert.alert('提示', '没有可用日记本,无法写日记',[
@ -140,6 +156,19 @@ export default class WritePage extends Component {
this.notebookListener.remove();
}
resetDraftTimer() {
if(this.draftTimer) {
clearInterval(this.draftTimer);
}
this.draftTimer = setInterval(() => {
let content = this.state.content;
if(content) {
Token.setDraft(content);
}
}, 5000);
}
openModal() {
this.contentInput.blur();
this.setState({modalVisible: true});

View file

@ -2,7 +2,7 @@ import AsyncStorage from '@react-native-community/async-storage';
var base64 = require('base-64');
class TokenManager {
class Token {
generateToken(username, password) {
return 'Basic ' + base64.encode(username + ":" + password);
@ -101,4 +101,4 @@ class TokenManager {
}
export default new TokenManager()
export default new Token()