mirror of
https://github.com/timepill/timepill-app.git
synced 2025-04-30 09:59:31 +08:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
d169cf348a
7 changed files with 143 additions and 63 deletions
|
@ -2,21 +2,11 @@ import React, {Component} from 'react';
|
||||||
import {Image, StyleSheet, Text, View, TouchableOpacity} from 'react-native';
|
import {Image, StyleSheet, Text, View, TouchableOpacity} from 'react-native';
|
||||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||||
|
|
||||||
|
import UserIcon from '../userIcon';
|
||||||
import Touchable from '../touchable';
|
import Touchable from '../touchable';
|
||||||
import Color from '../../style/color';
|
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 {
|
export default class Notification extends Component {
|
||||||
|
|
||||||
_onDeletePress(msg) {
|
_onDeletePress(msg) {
|
||||||
|
@ -28,7 +18,6 @@ export default class Notification extends Component {
|
||||||
if(msg && msg.type) {
|
if(msg && msg.type) {
|
||||||
if(msg.type == 1) {
|
if(msg.type == 1) {
|
||||||
return this.renderComment(msg);
|
return this.renderComment(msg);
|
||||||
|
|
||||||
} else if(msg.type == 2) {
|
} else if(msg.type == 2) {
|
||||||
return this.renderFollow(msg);
|
return this.renderFollow(msg);
|
||||||
} else if(msg.type == 3) {
|
} else if(msg.type == 3) {
|
||||||
|
@ -48,14 +37,43 @@ export default class Notification extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderComment(msg) {
|
renderComment(msg) {
|
||||||
const users = unique(msg.list.map(it => it.content.author.name)).join('、');
|
const max = 5;
|
||||||
const body = `${users} 回复了你`;
|
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 (
|
return (
|
||||||
<Touchable key={msg.link_id} onPress={() => this.props.onCommentPress(msg)}>
|
<Touchable key={msg.link_id} onPress={() => this.props.onCommentPress(msg)}>
|
||||||
<View style={localStyle.container}>
|
<View style={localStyle.container}>
|
||||||
<Ionicons name="ios-text" size={16} style={localStyle.icon} color={Color.light} />
|
<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)}
|
{this.renderDeleteButton(msg)}
|
||||||
</View>
|
</View>
|
||||||
</Touchable>
|
</Touchable>
|
||||||
|
@ -63,13 +81,17 @@ export default class Notification extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderFollow(msg) {
|
renderFollow(msg) {
|
||||||
const body = `${msg.content.user.name} 关注了你`;
|
const userIcon = msg.link_user_icon;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Touchable key={msg.link_id} onPress={() => this.props.onFollowPress(msg)}>
|
<Touchable key={msg.link_id} onPress={() => this.props.onFollowPress(msg)}>
|
||||||
<View style={localStyle.container}>
|
<View style={localStyle.container}>
|
||||||
<Ionicons name="ios-heart" size={16} style={localStyle.icon} color='#d9534f' />
|
<Ionicons name="ios-heart" size={14} style={localStyle.icon} color='#d9534f' />
|
||||||
<Text key={msg.link_id} style={localStyle.text}>{body}</Text>
|
<UserIcon
|
||||||
|
iconUrl={userIcon}
|
||||||
|
width={24} height={24}
|
||||||
|
/>
|
||||||
|
<Text style={localStyle.text}>关注了你</Text>
|
||||||
{this.renderDeleteButton(msg)}
|
{this.renderDeleteButton(msg)}
|
||||||
</View>
|
</View>
|
||||||
</Touchable>
|
</Touchable>
|
||||||
|
@ -77,7 +99,11 @@ export default class Notification extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLike(msg) {
|
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 (
|
return (
|
||||||
<Touchable key={msg.link_id} onPress={() => this.props.onLikePress(msg)}>
|
<Touchable key={msg.link_id} onPress={() => this.props.onLikePress(msg)}>
|
||||||
|
@ -89,7 +115,12 @@ export default class Notification extends Component {
|
||||||
}
|
}
|
||||||
style={localStyle.icon2}
|
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)}
|
{this.renderDeleteButton(msg)}
|
||||||
</View>
|
</View>
|
||||||
</Touchable>
|
</Touchable>
|
||||||
|
@ -109,17 +140,18 @@ const localStyle = StyleSheet.create({
|
||||||
icon: {
|
icon: {
|
||||||
marginRight: 10,
|
marginRight: 10,
|
||||||
marginTop: 1,
|
marginTop: 1,
|
||||||
lineHeight: 20
|
lineHeight: 28
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
lineHeight: 20
|
lineHeight: 28
|
||||||
},
|
},
|
||||||
icon2: {
|
icon2: {
|
||||||
width: 15,
|
width: 15,
|
||||||
height: 15,
|
height: 15,
|
||||||
marginRight: 10,
|
marginLeft: -1,
|
||||||
marginTop: 4,
|
marginRight: 9,
|
||||||
|
marginTop: 7,
|
||||||
},
|
},
|
||||||
delete: {
|
delete: {
|
||||||
lineHeight: 20,
|
lineHeight: 20,
|
||||||
|
|
|
@ -34,6 +34,7 @@ export default class NotificationList extends Component {
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
let notifications = await this.getMessages();
|
let notifications = await this.getMessages();
|
||||||
|
|
||||||
this.notificationsData = notifications;
|
this.notificationsData = notifications;
|
||||||
this.setNotifications(notifications);
|
this.setNotifications(notifications);
|
||||||
this.setState({error: false});
|
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) {
|
_onCommentPress(msg) {
|
||||||
Navigation.push(this.props.componentId, {
|
Navigation.push(this.props.componentId, {
|
||||||
component: {
|
component: {
|
||||||
|
@ -159,7 +183,7 @@ export default class NotificationList extends Component {
|
||||||
_onLikePress(msg) {
|
_onLikePress(msg) {
|
||||||
Navigation.push(this.props.componentId, {
|
Navigation.push(this.props.componentId, {
|
||||||
component: {
|
component: {
|
||||||
name: 'User',
|
name: 'DiaryDetail',
|
||||||
options: {
|
options: {
|
||||||
bottomTabs: {
|
bottomTabs: {
|
||||||
visible: false,
|
visible: false,
|
||||||
|
@ -170,7 +194,7 @@ export default class NotificationList extends Component {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
passProps: {
|
passProps: {
|
||||||
user: msg.content.user
|
diaryId: msg.content.dairy_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -199,6 +223,7 @@ export default class NotificationList extends Component {
|
||||||
renderItem={({item}) => {
|
renderItem={({item}) => {
|
||||||
return (
|
return (
|
||||||
<Notification msg={item}
|
<Notification msg={item}
|
||||||
|
onUserIconPress={this._onUserIconPress.bind(this)}
|
||||||
onCommentPress={this._onCommentPress.bind(this)}
|
onCommentPress={this._onCommentPress.bind(this)}
|
||||||
onFollowPress={this._onFollowPress.bind(this)}
|
onFollowPress={this._onFollowPress.bind(this)}
|
||||||
onLikePress={this._onLikePress.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,
|
|
||||||
// };
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,7 @@ export default class UserIcon extends Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Avatar rounded
|
<Avatar rounded containerStyle={localStyle.container}
|
||||||
containerStyle={localStyle.container}
|
|
||||||
width={this.props.width || 40}
|
width={this.props.width || 40}
|
||||||
height={this.props.height || 40}
|
height={this.props.height || 40}
|
||||||
source={{uri: this.state.iconUrl}}
|
source={{uri: this.state.iconUrl}}
|
||||||
|
|
|
@ -40,15 +40,6 @@ export default class NotificationPage extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
Navigation.events().bindComponent(this);
|
Navigation.events().bindComponent(this);
|
||||||
|
|
||||||
// const ds = new ListView.DataSource({
|
|
||||||
// rowHasChanged: (r1, r2) => r1 !== r2
|
|
||||||
// });
|
|
||||||
// this.state = ({
|
|
||||||
// messages: [],
|
|
||||||
// messagesDataSource: ds,
|
|
||||||
// refreshing: true,
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
navigationButtonPressed({buttonId}) {
|
navigationButtonPressed({buttonId}) {
|
||||||
|
|
|
@ -132,6 +132,18 @@ export default class UserPage extends Component {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if(this.userId) {
|
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)
|
Api.getRelation(this.userId)
|
||||||
.then(re => {
|
.then(re => {
|
||||||
this.followed = re;
|
this.followed = re;
|
||||||
|
@ -146,7 +158,8 @@ export default class UserPage extends Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.notebookListener = DeviceEventEmitter.addListener(Event.updateNotebooks, (param) => {
|
this.notebookListener = DeviceEventEmitter.addListener(Event.updateNotebooks, (param) => {
|
||||||
|
|
|
@ -24,7 +24,8 @@ import {Icon} from '../style/icon';
|
||||||
import Color from '../style/color';
|
import Color from '../style/color';
|
||||||
import Api from '../util/api';
|
import Api from '../util/api';
|
||||||
import Msg from '../util/msg';
|
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 NotebookLine from '../component/notebook/notebookLine';
|
||||||
import ImageAction from '../component/image/imageAction'
|
import ImageAction from '../component/image/imageAction'
|
||||||
|
@ -54,6 +55,8 @@ export default class WritePage extends Component {
|
||||||
fadeAnimOpacity: new Animated.Value(0),
|
fadeAnimOpacity: new Animated.Value(0),
|
||||||
fadeAnimHeight: new Animated.Value(0)
|
fadeAnimHeight: new Animated.Value(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.draftTimer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static options(passProps) {
|
static options(passProps) {
|
||||||
|
@ -102,6 +105,9 @@ export default class WritePage extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
closePage() {
|
closePage() {
|
||||||
|
clearInterval(this.draftTimer);
|
||||||
|
Token.setDraft('');
|
||||||
|
|
||||||
this.contentInput.blur();
|
this.contentInput.blur();
|
||||||
if (this.diary || this.topic) {
|
if (this.diary || this.topic) {
|
||||||
Navigation.pop(this.props.componentId);
|
Navigation.pop(this.props.componentId);
|
||||||
|
@ -112,10 +118,20 @@ export default class WritePage extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
Token.getDraft().then(draft => {
|
||||||
|
if(draft) {
|
||||||
|
this.setState({
|
||||||
|
content: draft,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.resetDraftTimer();
|
||||||
|
|
||||||
this.loadNotebook().then(notebookCount => {
|
this.loadNotebook().then(notebookCount => {
|
||||||
if(notebookCount > 0) {
|
if(notebookCount > 0) {
|
||||||
InteractionManager.runAfterInteractions(() => {
|
InteractionManager.runAfterInteractions(() => {
|
||||||
this && this.contentInput && this.contentInput.focus();
|
this.contentInput && this.contentInput.focus();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Alert.alert('提示', '没有可用日记本,无法写日记',[
|
Alert.alert('提示', '没有可用日记本,无法写日记',[
|
||||||
|
@ -140,6 +156,19 @@ export default class WritePage extends Component {
|
||||||
this.notebookListener.remove();
|
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() {
|
openModal() {
|
||||||
this.contentInput.blur();
|
this.contentInput.blur();
|
||||||
this.setState({modalVisible: true});
|
this.setState({modalVisible: true});
|
||||||
|
|
|
@ -2,7 +2,7 @@ import AsyncStorage from '@react-native-community/async-storage';
|
||||||
var base64 = require('base-64');
|
var base64 = require('base-64');
|
||||||
|
|
||||||
|
|
||||||
class TokenManager {
|
class Token {
|
||||||
|
|
||||||
generateToken(username, password) {
|
generateToken(username, password) {
|
||||||
return 'Basic ' + base64.encode(username + ":" + password);
|
return 'Basic ' + base64.encode(username + ":" + password);
|
||||||
|
@ -101,4 +101,4 @@ class TokenManager {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new TokenManager()
|
export default new Token()
|
||||||
|
|
Loading…
Reference in a new issue