Authored by 于良

收到的赞页面 review by 盖剑秋

... ... @@ -42,6 +42,7 @@ import SectionContainer from './containers/SectionContainer';
import UserContainer from './containers/UserContainer';
import UserThatNotMeContainer from './containers/UserThatNotMeContainer';
import MessageCenterContainer from './containers/MessageCenterContainer';
import LikeMessageContainer from './containers/LikeMessageContainer';
import SubjectPostContainer from './containers/SubjectPostContainer';
import PostingContainer from './containers/PostingContainer';
import SettingContainer from './containers/UserSettingContainer';
... ... @@ -216,6 +217,14 @@ export default function community(platform) {
/>
<Scene
key="LikeMessage"
title="收到的赞"
hideNavBar={false}
component={LikeMessageContainer}
initial={false}
/>
<Scene
key="Setting"
title="社区资料"
hideNavBar={false}
... ...
... ... @@ -83,7 +83,7 @@ let styles = StyleSheet.create({
fontFamily: 'Helvetica Light',
color: 'black',
fontSize: 13,
width: 130,
maxWidth: 130,
},
owner: {
color: '#4a90e2',
... ...
'use strict';
import React from 'react';
import ReactNative from 'react-native';
import ImmutablePropTypes from 'react-immutable-proptypes';
import UserBrief from '../home/UserBrief';
import SlicedImage from '../../../common/components/SlicedImage';
const {
View,
Text,
Image,
TouchableOpacity,
StyleSheet,
Dimensions,
} = ReactNative;
export default class LikeCell extends React.Component {
static propTypes = {
data: ImmutablePropTypes.contains({
user: ImmutablePropTypes.contains({
avatar: React.PropTypes.string,
uid: React.PropTypes.number,
nickName: React.PropTypes.string,
}),
timeago: React.PropTypes.string,
title: React.PropTypes.string,
post: ImmutablePropTypes.contains({
id: React.PropTypes.number,
thumb: React.PropTypes.string,
sectionId: React.PropTypes.string,
}),
}),
onPressPost: React.PropTypes.func,
onPressAvatar: React.PropTypes.func,
};
constructor(props) {
super (props);
}
render() {
let data = this.props.data.toJS();
let {user, title, timeago, post} = data;
return (
<TouchableOpacity
style={styles.row}
activeOpacity={0.8}
onPress={() => {
this.props.onPressPost && this.props.onPressPost(post.id);
}}
>
<UserBrief
avatar={user.avatar}
name={user.nickName}
timeago={timeago}
onPressAvatar={() => {
this.props.onPressAvatar && this.props.onPressAvatar(user.uid);
}}
/>
<Text style={styles.title} numberOfLines={1}>{title}</Text>
<SlicedImage
style={styles.thumb}
source={{uri: post.thumb}}
defaultSource={require('../../images/message/text_default.png')}
/>
</TouchableOpacity>
);
}
}
let styles = StyleSheet.create({
row: {
backgroundColor: 'white',
paddingLeft: 17,
paddingRight: 17,
height: 65,
flexDirection: 'row',
},
title: {
fontSize: 13,
color: '#8b8b8b',
marginTop: 20,
marginLeft: 10,
},
thumb: {
width: 50,
height: 50,
position: 'absolute',
marginTop: 7.5,
right: 17,
},
});
... ...
... ... @@ -2,12 +2,13 @@
import React from 'react';
import ReactNative from 'react-native';
import LikeCell from './LikeCell';
import LoadMoreIndicator from '../../../common/components/LoadMoreIndicator';
const {
View,
Text,
Image,
TextInput,
ListView,
StyleSheet,
Platform,
Dimensions,
... ... @@ -15,27 +16,68 @@ const {
export default class LikeMessage extends React.Component {
static propTypes = {
}
constructor(props) {
super(props);
this._renderRow = this._renderRow.bind(this);
this._renderSeparator = this._renderSeparator.bind(this);
this.dataSource = new ListView.DataSource({
rowHasChanged: (r1, r2) => !Immutable.is(r1, r2),
});
}
_renderSeparator(sectionID, rowID, adjacentRowHighlighted) {
return (
<View key={'separator' + sectionID + rowID} style={styles.separator}/>
);
}
_renderSeparator() {
_renderRow(rowData, sectionID, rowID, highlightRow) {
return (
<View style={styles.separator}/>
<LikeCell
key={sectionID + rowID}
data={rowData}
onPressPost={this.props.onPressPost}
onPressAvatar={this.props.onPressAvatar}
/>
);
}
render() {
let {list, endReached, isLoadingMore, isFetching} = this.props;
return (
<View style={styles.container}>
<Text>收到的赞</Text>
<ListView
ref={(c) => {
this.listView = c;
}}
dataSource={this.dataSource.cloneWithRows(list.toArray())}
renderRow={this._renderRow}
renderSeparator={this._renderSeparator}
enableEmptySections={true}
enablePullToRefresh={false}
onEndReached={() => {
this.props.onEndReached && this.props.onEndReached();
}}
renderFooter={()=>{
if (endReached) {
return <LoadMoreIndicator
isVisible={true}
text={'没有更多啦'}
/>
} else {
return <LoadMoreIndicator
isVisible={isLoadingMore}
animating={isFetching}
/>
}
}}
/>
</View>
);
)
}
}
... ... @@ -43,11 +85,13 @@ export default class LikeMessage extends React.Component {
let {width, height} = Dimensions.get('window');
let navbarHeight = (Platform.OS === 'android') ? 50 : 64;
let styles = StyleSheet.create({
container: {
top: navbarHeight,
height: height-navbarHeight,
backgroundColor: 'white',
flex: 1,
},
separator: {
height: 0.5,
backgroundColor: '#e0e0e0',
},
});
... ...
... ... @@ -150,7 +150,7 @@ export default class UserThatNotMe extends React.Component {
}
render() {
let {posts, endReached, isRefreshing, isLoadingMore, isFetching, navigationState} = this.props;
let {posts, endReached, isRefreshing, isLoadingMore, isFetching} = this.props;
let dataSource = {
posts: posts.toArray(),
}
... ... @@ -228,9 +228,4 @@ let styles = StyleSheet.create({
height: 0.5,
backgroundColor: '#e0e0e0',
},
fly: {
position: 'absolute',
right: 20,
bottom: 20,
},
});
... ...
... ... @@ -7,6 +7,7 @@ import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import Immutable, {Map, List} from 'immutable';
import {Actions} from 'react-native-router-flux';
import Home from '../components/home/Home';
... ... @@ -14,7 +15,7 @@ import * as homeActions from '../reducers/home/homeActions';
import * as appActions from '../reducers/app/appActions';
import * as userActions from '../reducers/user/userActions';
import * as postingActions from '../reducers/posting/postingActions';
import {Actions} from 'react-native-router-flux';
const {
View,
... ...
... ... @@ -4,13 +4,14 @@ import React from 'react';
import ReactNative from 'react-native';
import Immutable, {Map} from 'immutable';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {Actions} from 'react-native-router-flux';
import LikeMessage from '../components/message/LikeMessage';
import * as messageActions from '../reducers/message/messageActions';
import * as homeActions from '../reducers/home/homeActions';
import {shouldShowTabBar, shouldHideTabBar} from '../utils/tabBar';
const {
Text,
... ... @@ -18,10 +19,12 @@ const {
StyleSheet,
Dimensions,
Platform,
InteractionManager,
} = ReactNative;
const actions = [
messageActions,
homeActions,
];
function mapStateToProps(state) {
... ... @@ -45,20 +48,60 @@ function mapDispatchToProps(dispatch) {
class LikeMessageContainer extends React.Component {
constructor(props) {
super(props);
this._onPressPost = this._onPressPost.bind(this);
this._onPressAvatar = this._onPressAvatar.bind(this);
this._onEndReached = this._onEndReached.bind(this);
}
componentDidMount() {
if (shouldHideTabBar(this.props.navigationState)) {
ReactNative.NativeModules.YH_CommunityHelper.hideTabBar();
}
this._onEndReached();
}
componentWillUnmount() {
if (shouldShowTabBar(this.props.navigationState)) {
Actions.refresh({key: 'Home', showNativeTabBar: true});
}
}
_onPressPost(id) {
this.props.actions.goToPost(id);
}
_onPressAvatar(uid) {
this.props.actions.goToUserOrMe(uid);
}
_onEndReached() {
InteractionManager.runAfterInteractions(() => {
this.props.actions.likeMessage(false);
});
}
render() {
let {like} = this.props.message;
return (
<View style={styles.container}>
<LikeMessage
list={like.list}
isFetching={like.isFetching}
endReached={like.endReached}
isLoadingMore={like.isFetching}
onEndReached={this._onEndReached}
onPressPost={this._onPressPost}
onPressAvatar={this._onPressAvatar}
/>
</View>
);
}
}
let {width, height} = Dimensions.get('window');
let navbarHeight = (Platform.OS === 'android') ? 50 : 64;
... ...
... ... @@ -2,7 +2,7 @@
import {Actions} from 'react-native-router-flux';
import MessageService from '../../services/MessageService';
// import timeago from 'timeago.js';
import timeago from '../../utils/timeago';
const {
GO_TO_MESSAGE_CENTER,
... ... @@ -15,30 +15,63 @@ const {
} = require('../../constants/actionTypes').default;
export function likeMessageRequest() {
export function likeMessageRequest(ptr) {
return {
type: LIKE_MESSAGE_REQUEST,
payload: ptr
};
}
export function likeMessageSuccess() {
export function likeMessageSuccess(json) {
return {
type: LIKE_MESSAGE_SUCCESS,
payload: json
};
}
export function likeMessageFailue() {
export function likeMessageFailue(error) {
return {
type: LIKE_MESSAGE_FAILURE,
payload: error
};
}
export function likeMessage() {
export function likeMessage(ptr = false) {
return (dispatch, getState) => {
dispatch(likeMessageRequest());
return new MessageService().messageList(uid)
let {user, message} = getState();
// 接口请求跳出的条件:
// 前置条件:下拉刷新优先级高于上拉加载
if (ptr) {
//下拉刷新直接执行
} else {
// 1.当次请求不是下拉刷新,同时正在进行下拉刷新的请求,跳出
// 2.当次请求不是下拉刷新,同时接口请求正在加载中, 跳出
// 3.当次请求不是下拉刷新,数据已全部加载完成,跳出
if (message.like.ptr || message.like.isFetching || message.like.endReached || message.like.error) {
return;
}
}
dispatch(likeMessageRequest(ptr));
let uid = user.profile.uid;
let lastedTime = 0;
if (!ptr) {
lastedTime = message.like.lastedTime;
}
let type = 2; // 点赞列表
let limit = 10;
return new MessageService().messageList(uid, type, lastedTime, limit)
.then(json => {
dispatch(likeMessageSuccess(json));
let payload = parseLikeMessage(json);
if (!ptr) {
let oldList = message.like.list.toJS();
let list = [...oldList, ...payload.list];
payload.list = list;
}
dispatch(likeMessageSuccess(payload));
})
.catch(error => {
dispatch(likeMessageFailue(error));
... ... @@ -46,30 +79,68 @@ export function likeMessage() {
};
}
function parseLikeMessage(json) {
let {lastedTime, list} = json;
let messages = [];
list && list.map((item, i) => {
let id = item.id ? item.id : 0;
let title = item.title ? item.title : '';
let type = item.type ? item.type : 0;
let isRead = item.isRead ? item.isRead : 'Y';
let createTime = item.createTime;
let timeagoStr = timeago(createTime);
// 页面跳转
export function goToStatsPage(type) {
switch (type) {
case GO_TO_SYS_MESSAGE:
{
Actions.SystemMessage();
return {
type: GO_TO_SYS_MESSAGE,
let user = {};
let post = {};
let {content} = item;
if (content) {
let {userInfo, postInfo} = content;
if (userInfo) {
let nickName = userInfo.nickName ? userInfo.nickName : '';
let avatar = userInfo.headIcon ? userInfo.headIcon : '';
let uid = userInfo.uid ? userInfo.uid : 0;
let sign = userInfo.signature ? userInfo.signature : '';
let backgroundImage = userInfo.bgPic ? userInfo.bgPic : '';
user = {
nickName,
avatar,
uid,
sign,
backgroundImage,
};
}
}
break;
case GO_TO_LIKE_MESSAGE:
{
Actions.LikeMessage();
return {
type: GO_TO_LIKE_MESSAGE,
if (postInfo) {
let sectionId = postInfo.sectionId ? postInfo.sectionId : '';
let postId = postInfo.postId ? postInfo.postId : 0;
postId = parseInt(postId);
let thumb = postInfo.content ? postInfo.content : '';
post = {
id: postId,
thumb,
sectionId,
};
}
}
break;
default:
}
let message = {
id,
title,
type,
isRead,
createTime,
timeago: timeagoStr,
user,
post,
}
messages.push(message);
});
let endReached = messages.length == 0;
return {
lastedTime,
list: messages,
endReached,
}
}
... ...
... ... @@ -8,6 +8,7 @@ let InitialState = Record({
name: null,
sign:null,
like: new (Record({
ptr: false,
isFetching: false,
error: null,
lastedTime: 0,
... ...
... ... @@ -4,9 +4,9 @@ import Immutable, {Map} from 'immutable';
const {
SETTING_SAVE_REQUEST,
SETTING_SAVE_SUCCESS,
SETTING_SAVE_FAILURE,
LIKE_MESSAGE_REQUEST,
LIKE_MESSAGE_SUCCESS,
LIKE_MESSAGE_FAILURE,
} = require('../../constants/actionTypes').default;
... ... @@ -14,13 +14,28 @@ const initialState = new InitialState;
export default function message(state = initialState, action) {
if (!(state instanceof InitialState)) return initialState.merge(state);
// switch (action.type) {
// case SETTING_SAVE_REQUEST:
//
// break;
// default:
//
// }
switch (action.type) {
case LIKE_MESSAGE_REQUEST: {
let nextState = state.setIn(['like', 'isFetching'], true)
.setIn(['like', 'error'], null);
return nextState;
}
case LIKE_MESSAGE_SUCCESS: {
let {lastedTime, list, endReached} = action.payload;
let nextState = state.setIn(['like', 'isFetching'], false)
.setIn(['like', 'error'], null)
.setIn(['like', 'lastedTime'], lastedTime)
.setIn(['like', 'endReached'], endReached)
.setIn(['like', 'list'], Immutable.fromJS(list));
return nextState;
}
case LIKE_MESSAGE_FAILURE:
return state.setIn(['like', 'isFetching'], false)
.setIn(['like', 'error'], action.payload);
}
return state;
}
... ...