Authored by 于良

Merge branch 'guang' into 5.4

Conflicts:
	js/plustar/Plustar.js
export function urlAddParamOfType(url, type='0') {
if (!type) {
return url;
}
let strs= new Array();
let dataString = '';
if (url.indexOf('yohobuy=') !== -1) {
strs = url.split("yohobuy=");
if (strs.length == 1) {
dataString = strs[0];
} else {
dataString = strs[1];
}
} else {
strs = url.split("yohobuy=");
if (strs.length == 1) {
dataString = strs[0];
} else {
dataString = strs[1];
}
}
var obj = JSON.parse(dataString); //由JSON字符串转换为JSON对象
obj.params.type = type + ''; // params增加type参数
let totalUrlWithType = "yohobuy=" + JSON.stringify(obj);
if (strs.length > 1) {
totalUrlWithType = strs[0] + totalUrlWithType;
}
return totalUrlWithType;
}
\ No newline at end of file
... ...
... ... @@ -12,7 +12,7 @@ import Header from './Header';
import MoreLink from './MoreLink';
import GoodsGroupHeader from './GoodsGroupHeader';
import GoodsGroupList from './GoodsGroupList';
import Small_pic from './Small_pic';
import SmallPic from './SmallPic';
import Weixin from './Weixin';
import LoadingIndicator from '../../../common/components/LoadingIndicator';
... ... @@ -85,7 +85,7 @@ export default class Detail extends Component {
);
}else if (template_name == 'small_pic') {
return (
<Small_pic resource={rowData}/>
<SmallPic resource={rowData}/>
);
}else if (template_name == 'goods_group') {
let {resource} = this.props;
... ... @@ -95,7 +95,7 @@ export default class Detail extends Component {
return (
<View style={styles.GoodsGroupHeader} onLayout={this.onLayout.bind(this, rowID)}>
<GoodsGroupHeader resource={{rowData,goods_group_Filter}} onPressFilter= {this.props.onPressFilter} scrollTo={this.scrollTo}/>
<GoodsGroupHeader resource={rowData} goods_group_Filter={goods_group_Filter} onPressFilter= {this.props.onPressFilter} scrollTo={this.scrollTo}/>
<GoodsGroupList resource={list} onPressProduct={this.props.onPressProduct}/>
</View>
);
... ... @@ -114,11 +114,11 @@ export default class Detail extends Component {
);
}else if (sectionID == 'detailBrand') {
return (
<DetailBrand resource={rowData}/>
<DetailBrand resource={rowData} onPressBrand={this.props.onPressBrand}/>
);
}else if (sectionID == 'detailOtherArticle') {
return (
<OtherArticle resource={rowData}/>
<OtherArticle resource={rowData} onPressArticle={this.props.onPressArticle}/>
);
} else if (sectionID == 'tags'){
return (
... ... @@ -150,11 +150,11 @@ export default class Detail extends Component {
detailOtherArticle: [otherArticle],
};
let isFetching = content.isFetching;
let isFetching = content.isFetching || article.isFetching || author.isFetching;
return (
<View style={styles.container}>
<ListView
{!isFetching?<ListView
ref={(ref)=>this.listView=ref}
contentContainerStyle={styles.contentContainer}
enableEmptySections={true}
... ... @@ -162,7 +162,7 @@ export default class Detail extends Component {
dataSource={this.dataSource.cloneWithRowsAndSections(dataSource)}
renderRow={this.renderRow}
renderHeader={this.renderHeader}
/>
/>:null}
<LoadingIndicator
isVisible={isFetching}
/>
... ...
... ... @@ -33,20 +33,20 @@ export default class DetailBrand extends React.Component {
}
}
_renderRow(rowData, sectionID, rowID) {
let {url} = rowData;
if ((rowID+1)%4 == 0) {
return (
<View style={styles.lastCell}>
<Image style={styles.cellImg} source={{uri:rowData.thumb}}/>
<Text style={styles.cellTitle}>{rowData.name}</Text>
</View>
<TouchableOpacity style={styles.lastCell} onPress={()=>{this.props.onPressBrand&&this.props.onPressBrand(url)}}>
<Image style={styles.cellImg} source={{uri:rowData.thumb}}/>
<Text style={styles.cellTitle}>{rowData.name}</Text>
</TouchableOpacity>
);
} else {
return (
<View style={styles.cell}>
<Image style={styles.cellImg} source={{uri:rowData.thumb}}/>
<Text style={styles.cellTitle}>{rowData.name}</Text>
</View>
<TouchableOpacity style={styles.cell} onPress={()=>{this.props.onPressBrand&&this.props.onPressBrand(url)}}>
<Image style={styles.cellImg} source={{uri:rowData.thumb}}/>
<Text style={styles.cellTitle}>{rowData.name}</Text>
</TouchableOpacity>
);
}
}
... ... @@ -69,7 +69,6 @@ export default class DetailBrand extends React.Component {
renderRow={this._renderRow}
scrollEnabled={false}
scrollsToTop={false}
horizontal={true}
/>
</View>
);
... ... @@ -134,7 +133,7 @@ let styles = StyleSheet.create({
justifyContent: 'space-between',
},
cellImg: {
backgroundColor: 'gray',
backgroundColor: 'white',
marginLeft: (cellWidth-55)/2,
width: 55,
height: 55,
... ...
... ... @@ -97,12 +97,13 @@ export default class DetailText extends React.Component {
let template_name = resource.get('data');
let text = template_name.get('text');
text = '<html><body>' + text + '</body></html>';
text = '<html><style type="text/css">img {max-width: 100%;}</style><body>' + text + '</body></html>'
let hasLink = false;
if (text.indexOf('<a href=') >= 0) {
hasLink = true;
}
return (
<View style={{width: width,height: this.state.realContentHeight,backgroundColor: 'white'}}>
<WebView style={{width: width-40,height: this.state.realContentHeight,backgroundColor: 'white',marginRight: 20,marginLeft: 20}}
... ... @@ -125,8 +126,5 @@ export default class DetailText extends React.Component {
let {width, height} = Dimensions.get('window');
let styles = StyleSheet.create({
webview_style: {
backgroundColor: 'red',
height: 100,
},
});
... ...
... ... @@ -62,16 +62,15 @@ export default class GoodsGroupHeader extends React.Component {
}
render() {
let {resource} = this.props;
let rowData = resource?resource.rowData:null;
this.selectedIndex = resource?resource.goods_group_Filter:0;
let {resource,goods_group_Filter} = this.props;
this.selectedIndex = goods_group_Filter;
let list = rowData.get('data');
let list = resource?resource.get('data'):null;
if (!list || list.size == 0) {
return null;
}
let n = ((Math.ceil(this.selectedIndex)+1) *2 - 1)*10 + (itemW-20) * ((Math.ceil(this.selectedIndex)+1) - 0.5) - 8;
let arrow_up_offset = ((Math.ceil(this.selectedIndex)+1) *2 - 1)*10 + (itemW-20) * ((Math.ceil(this.selectedIndex)+1) - 0.5) - 8;
return (
<View style={[styles.container]}>
... ... @@ -86,8 +85,8 @@ export default class GoodsGroupHeader extends React.Component {
<View style={{width: width,height: 10,backgroundColor: 'white',}}>
</View>
<View style={{width: width,height: 9,backgroundColor: 'white'}}>
<View style={{position: 'absolute',marginTop:8,width: width,height: 1,backgroundColor: '#e0e0e0'}}/>
<Image source={require('../../image/global_arrow_up.png')} style={{marginLeft: n,width: 16,height: 9,backgroundColor: 'transparent'}}>
<View style={styles.line}/>
<Image source={require('../../image/global_arrow_up.png')} style={{marginLeft: arrow_up_offset,width: 16,height: 9,backgroundColor: 'transparent'}}>
</Image>
</View>
</View>
... ... @@ -116,4 +115,11 @@ let styles = StyleSheet.create({
height: itemH + 20,
backgroundColor:'white',
},
line: {
position: 'absolute',
marginTop:8,
width: width,
height: 1,
backgroundColor: '#e0e0e0',
}
});
... ...
... ... @@ -48,19 +48,21 @@ export default class Header extends React.Component {
let author_data = author.get('data');
let article_data = article.get('data');
let hasData = true;
if (!author_data || !article_data) {
return null;
hasData = false;
}
let author_desc = author_data.get('author_desc');
let author_avatar = author_data.get('avatar');
let author_name = author_data.get('name');
let author_url = author_data.get('url');
let author_desc = hasData?author_data.get('author_desc'):'';
let author_avatar = hasData?author_data.get('avatar'):'';
let author_name = hasData?author_data.get('name'):'';
let author_url = hasData?author_data.get('url'):'';
let num = this.getStrSize(author_desc);
let article_title = article_data.get('article_title');
let pageViews = article_data.get('pageViews');
let publishTime = article_data.get('publishTime');
let article_title = hasData?article_data.get('article_title'):'';
let pageViews = hasData?article_data.get('pageViews'):'99999';
let publishTime = hasData?article_data.get('publishTime'):'12月12日 12:00';
return(
<View style={styles.contentContainer}>
<TouchableOpacity activeOpacity={0.5} onPress={() => {
... ... @@ -69,7 +71,7 @@ export default class Header extends React.Component {
<View style={styles.header}>
<Image source={{uri: author_avatar}} style={styles.thumb}></Image>
<Text style={styles.name}>{author_name}</Text>
{(num > 25)?null:<Text style={styles.desc}>{author_desc}</Text>}
{(num > 25)?null:<Text style={styles.desc} numberOfLines={1}>{author_desc}</Text>}
</View>
</TouchableOpacity>
{(num > 25)?<Text style={styles.desc2}>{author_desc}</Text>:null}
... ... @@ -117,9 +119,9 @@ let styles = StyleSheet.create({
desc2: {
marginLeft: 20,
color: '#e5e5e5',
height: 40,
width: width,
fontSize: 15,
minHeight: 40,
},
article_title: {
marginLeft: 20,
... ...
... ... @@ -21,7 +21,7 @@ export default class OtherArticle extends React.Component {
super(props);
this._renderRow = this._renderRow.bind(this);
this.dataSource = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1.key != r2.key,
rowHasChanged: (r1, r2) => !Immutable.is(r1, r2),
});
}
... ... @@ -34,27 +34,26 @@ export default class OtherArticle extends React.Component {
}
_renderRow(rowData, sectionID, rowID) {
let {url} = rowData;
return (
<View style={styles.cell}>
<Image style={styles.cellImage} source={{uri:rowData.thumb}}/>
<TouchableOpacity style={styles.cell} onPress={()=>{this.props.onPressArticle&&this.props.onPressArticle(rowData.get('url'))}}>
<Image style={styles.cellImage} source={{uri:rowData.get('thumb')}}/>
<View style={styles.cellContent}>
<Text style={styles.cellTitle} numberOfLines={2}>
{rowData.title}
{rowData.get('title')}
</Text>
<View style={styles.bottomContent}>
<Image source={require('../../image/time_icon.png')} style={styles.clockIcon}/>
<Text style={styles.timeText}>{rowData.publishTime}</Text>
<Text style={styles.timeText}>{rowData.get('publishTime')}</Text>
</View>
</View>
</View>
</TouchableOpacity>
);
}
render() {
let {data} = this.props.resource.toJS();
if (!data.length) {
return null;
}
let data = this.props.resource.get('data').toArray();
return(
<View style={styles.container}>
<View style={styles.headerView}>
... ... @@ -63,7 +62,7 @@ export default class OtherArticle extends React.Component {
<ListView
style={styles.articleContainer}
enableEmptySections={true}
initialListSize={data.length}
initialListSize={data.size}
dataSource={this.dataSource.cloneWithRows(data)}
renderRow={this._renderRow}
scrollEnabled={false}
... ...
... ... @@ -38,7 +38,9 @@ export default class SingleImage extends React.Component {
let template_name = resource.get('data');
let src = template_name.get('src');
Image.getSize(src, (width, height) => {
this.setState({width, height});
if (this.imageView) {
this.setState({width, height});
}
});
}
... ... @@ -47,19 +49,17 @@ export default class SingleImage extends React.Component {
let template_name = resource.get('data');
let src = template_name.get('src');
return (
<View style={{width: Dimensions.get('window').width,height: (this.state.height/this.state.width)*Dimensions.get('window').width}}>
<Image
source={{uri: src}}
style={{width: Dimensions.get('window').width,height: (this.state.height/this.state.width)*Dimensions.get('window').width}}
>
</Image>
</View>
<Image
ref={(ref)=>this.imageView=ref}
source={{uri: src}}
style={{width: screenWidth,height: (this.state.height/this.state.width)*screenWidth}}
/>
);
return null;
}
};
let screenWidth = Dimensions.get('window').width;
let imageView = null;
let styles = StyleSheet.create({
});
... ...
... ... @@ -16,7 +16,7 @@ const {
} = ReactNative;
export default class Small_pic extends React.Component {
export default class SmallPic extends React.Component {
constructor(props) {
super(props);
this.state = {
... ...
... ... @@ -24,27 +24,33 @@ export default class Tags extends React.Component {
render() {
let {resource} = this.props;
let data = resource.get('data')?resource.get('data').toJS():null;
let tags = data?data.tags:[];
let data = resource.get('data') ? resource.get('data').toJS() : null;
let tags = data ? data.tags : [];
if (!tags||!tags.length) {
if (!tags || !tags.length) {
return null;
}
return(
return (
<View style={styles.container}>
<Image style={styles.tagImage}/>
<View style={styles.tagContainer}>
{tags.map(
(value, i) => {
return (
<Text style={styles.tag} onPress={()=>{this.props.onPressTag&&this.props.onPressTag(value.url)}}>{value.name}</Text>
);
}
)}
{tags.map((value, i) => {
return (
<Text
key={i}
style={styles.tag}
onPress={()=>{
this.props.onPressTag && this.props.onPressTag(value.url)
}}
>
{value.name}
</Text>
);
})}
</View>
</View>
);
return null;
}
};
... ...
... ... @@ -22,13 +22,10 @@ export default class Weixin extends React.Component {
super(props);
}
componentDidMount() {
}
render() {
let {resource} = this.props;
let data = resource.get('data')?resource.get('data').toJS():null;
let data = resource.get('data') ? resource.get('data').toJS() : null;
if (!data) {
return null;
}
... ...
... ... @@ -15,6 +15,7 @@ import ReactNative, {
import HeaderCell from './HeaderCell';
import ListCell from './ListCell';
import LoadMoreIndicator from '../../../common/components/LoadMoreIndicator';
import LoadingIndicator from '../../../common/components/LoadingIndicator';
export default class List extends Component {
... ... @@ -48,15 +49,27 @@ export default class List extends Component {
}
renderHeader() {
if (this.props.data.type == 'editor') {
return(
<HeaderCell resource={this.state.author}/>
);
} else {
return null;
}
return(
<HeaderCell resource={this.state.author}/>
);
}
renderRow(rowData,sectionID,rowID) {
let type = this.props.data.get('type');
return(
<ListCell resource={rowData}/>
<ListCell
resource={rowData}
type={type}
onPressCell={this.props.onPressCell}
onPressShare={this.props.onPressShare}
onPressLike={this.props.onPressLike}
onPressHeader={this.props.onPressHeader}
/>
);
}
... ... @@ -90,6 +103,9 @@ export default class List extends Component {
}
}}
/>
<LoadingIndicator
isVisible={isFetching}
/>
</View>
);
}
... ...
... ... @@ -38,12 +38,16 @@ export default class List extends Component {
}
_renderHeader() {
return null;
if (this.props.type == 'editor') {
return null;
}
return (
<TouchableOpacity onPress={()=>{this.props.onPressHeader&&this.props.onPressHeader(this.props.resource.author.url)}}>
<View style={styles.headerContainer}>
<Image style={styles.avatar} source={{uri:this.props.resource.author.avatar}}/>
<Text style={styles.name}>Sphinx</Text>
</View>
</TouchableOpacity>
)
}
... ... @@ -66,16 +70,27 @@ export default class List extends Component {
src,
title,
views_num,
url,
share,
id,
} = this.props.resource;
let urlAry = url.split('&');
let shareParam = {
title,
'content': intro,
'image': src,
'url': urlAry[0],
};
let bigPic = getSlicedUrl(src, 640, 640, 2);
let tagImg = tagMap[category_name];
if (!tagImg) {
tagImg = "../../image/chaopin_icon.png";
}
let likeImg = isPraise == 'N'?require('../../image/wsc_icon.png'):require('../../image/sc_icon.png');
let isLike = isPraise == 'N';
return (
<TouchableOpacity activeOpacity={0.5} onPress={() => {
// this.props.onPressBrandItem && this.props.onPressBrandItem(rowData.url, rowID);
this.props.onPressCell&&this.props.onPressCell(url);
}}>
<View style={styles.container}>
<View style={styles.sapatorView}/>
... ... @@ -92,10 +107,10 @@ export default class List extends Component {
<Text style={styles.text}>{publish_time}</Text>
<Image source={require('../../image/shared_view_icon.png')} style={styles.iconThumb}resizeMode={'contain'}></Image>
<Text style={styles.text}>{views_num}</Text>
<TouchableOpacity style={styles.likeButton}>
<TouchableOpacity style={styles.likeButton} onPress={()=>{this.props.onPressLike&&this.props.onPressLike(id, isLike)}}>
<Image source={likeImg}/>
</TouchableOpacity>
<TouchableOpacity style={styles.shareButton}>
<TouchableOpacity style={styles.shareButton} onPress={()=>{this.props.onPressShare&&this.props.onPressShare(shareParam)}}>
<Image source={require('../../image/shared_sharebuttom_highlighted.png')}/>
</TouchableOpacity>
</View>
... ... @@ -117,7 +132,7 @@ let styles = StyleSheet.create({
backgroundColor: 'white',
},
sapatorView: {
backgroundColor: '#f0f0f0',
backgroundColor: 'white',
width: width,
height: 16,
borderColor: 'rgb(215, 215, 215)',
... ...
... ... @@ -47,4 +47,6 @@ export default keyMirror({
SET_GOOESGROUP_FILTER: null,
SET_GOOESGROUP_Y: null,
LIKE_ARTICLE: null,
});
... ...
... ... @@ -18,7 +18,7 @@ import {Map} from 'immutable';
import * as detailActions from '../reducers/detail/detailActions';
import Detail from '../components/detail/Detail';
import {urlAddParamOfType} from '../../common/utils/urlHandler';
const actions = [
detailActions,
... ... @@ -47,8 +47,6 @@ class DetailContainer extends Component {
constructor(props) {
super(props);
this._onRefresh = this._onRefresh.bind(this);
this._onEndReached = this._onEndReached.bind(this);
this._onPressFilter = this._onPressFilter.bind(this);
this._onPressAuthor = this._onPressAuthor.bind(this);
this._onPressMoreLink = this._onPressMoreLink.bind(this);
... ... @@ -57,6 +55,8 @@ class DetailContainer extends Component {
this._onPressGoodY = this._onPressGoodY.bind(this);
this._onPressLink = this._onPressLink.bind(this);
this._onPressTag = this._onPressTag.bind(this);
this._onPressBrand = this._onPressBrand.bind(this);
this._onPressArticle = this._onPressArticle.bind(this);
}
componentDidMount() {
... ... @@ -70,18 +70,6 @@ class DetailContainer extends Component {
}
_onRefresh() {
InteractionManager.runAfterInteractions(() => {
});
}
_onEndReached() {
InteractionManager.runAfterInteractions(() => {
});
}
_onPressFilter(value) {
this.props.actions.setGoodsGroupFilter(value);
}
... ... @@ -91,6 +79,15 @@ class DetailContainer extends Component {
}
_onPressAuthor(url) {
let authorUrl = urlAddParamOfType(url, '11')
ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(authorUrl);
}
_onPressBrand(url) {
ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url);
}
_onPressArticle(url) {
ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url);
}
... ... @@ -99,7 +96,8 @@ class DetailContainer extends Component {
}
_onPressTag(url) {
ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url);
let taggedUrl = urlAddParamOfType(url, '12')
ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(taggedUrl);
}
_onPressMoreLink(url) {
ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url);
... ... @@ -125,12 +123,7 @@ class DetailContainer extends Component {
return (
<View style={styles.container}>
<Detail
ref={(c) => {
this.detail = c;
}}
resource={detail}
onRefresh={this._onRefresh}
onEndReached={this._onEndReached}
onPressFilter= {this._onPressFilter}
onPressAuthor={this._onPressAuthor}
onPressMoreLink={this._onPressMoreLink}
... ... @@ -139,6 +132,8 @@ class DetailContainer extends Component {
onPressGoodY={this._onPressGoodY}
onPressLink={this._onPressLink}
onPressTag={this._onPressTag}
onPressBrand={this._onPressBrand}
onPressArticle={this._onPressArticle}
/>
</View>
);
... ...
... ... @@ -19,7 +19,7 @@ import {Map} from 'immutable';
import * as listActions from '../reducers/list/listActions';
import List from '../components/list/List';
import {urlAddParamOfType} from '../../common/utils/urlHandler';
const actions = [
listActions,
... ... @@ -50,6 +50,10 @@ class ListContainer extends Component {
this._onRefresh = this._onRefresh.bind(this);
this._onEndReached = this._onEndReached.bind(this);
this._onPressCell = this._onPressCell.bind(this);
this._onPressShare = this._onPressShare.bind(this);
this._onPressLike = this._onPressLike.bind(this);
this._onPressHeader = this._onPressHeader.bind(this);
this.subscription = NativeAppEventEmitter.addListener(
'ChannelDidChangeEvent',
(reminder) => {
... ... @@ -66,12 +70,29 @@ class ListContainer extends Component {
this.subscription && this.subscription.remove();
}
_onPressCell(url) {
ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url);
}
_onPressHeader(url) {
let taggedUrl = urlAddParamOfType(url, '11')
ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(taggedUrl);
}
_onRefresh() {
InteractionManager.runAfterInteractions(() => {
this.props.actions.getArticleList(true);
});
}
_onPressShare(param) {
ReactNative.NativeModules.YH_CommonHelper.shareWithParam(param);
}
_onPressLike(article_id, isLike) {
this.props.actions.onPressLike(article_id, isLike);
}
_onEndReached() {
InteractionManager.runAfterInteractions(() => {
this.props.actions.getArticleList();
... ... @@ -89,7 +110,11 @@ class ListContainer extends Component {
this.sale = c;
}}
data={list}
onPressCell={this._onPressCell}
onEndReached={this._onEndReached}
onPressShare={this._onPressShare}
onPressLike={this._onPressLike}
onPressHeader={this._onPressHeader}
/>
</View>
);
... ...
... ... @@ -12,6 +12,7 @@ const {
GET_ARTICLE_LIST_SUCCESS,
GET_ARTICLE_LIST_FAILURE,
LIKE_ARTICLE,
} = require('../../constants/actionTypes').default;
export function setListType(type) {
... ... @@ -56,6 +57,45 @@ function getArticleListFailure(error) {
};
}
function likeArticle(json) {
return {
type: LIKE_ARTICLE,
payload: json,
}
}
export function onPressLike(article_id, isLike) {
return (dispatch, getState) => {
let {app, list} = getState();
let likeRequest = (article_id, uid, isLike) => {
dispatch(likeArticle({article_id, isLike}));
if (isLike) {
return new ListService(app.serviceHost).setArticleFavorite(article_id, uid)
}else {
return new ListService(app.serviceHost).cancleArticleFavorite(article_id, uid)
}
}
ReactNative.NativeModules.YH_CommonHelper.uid()
.then(uid => {
likeRequest(article_id, uid, isLike);
})
.catch(error => {
ReactNative.NativeModules.YH_CommonHelper.login()
.then(uid => {
likeRequest(article_id, uid, isLike);
})
.catch(error => {
});
});
};
}
export function getArticleList(reload = false) {
return (dispatch, getState) => {
... ...
... ... @@ -12,6 +12,8 @@ const {
GET_ARTICLE_LIST_SUCCESS,
GET_ARTICLE_LIST_FAILURE,
LIKE_ARTICLE,
} = require('../../constants/actionTypes').default;
const initialState = new InitialState;
... ... @@ -56,6 +58,25 @@ export default function listReducer(state=initialState, action) {
return newState;
}
case LIKE_ARTICLE: {
let {
article_id,
isLike,
} = action.payload;
let originAry = state.get('articles').get('list').toJS();
for (var i = 0; i < originAry.length; i++) {
if (originAry[i].id == article_id) {
console.log('......find....');
originAry[i].isPraise = isLike?'Y':'N';
}
}
let newState = state.setIn(['articles', 'list'], Immutable.fromJS(originAry));
return newState;
}
break;
case GET_ARTICLE_LIST_FAILURE: {
return state.setIn(['articles', 'isFetching'], false)
.setIn(['articles', 'error'], action.payload)
... ...
... ... @@ -11,18 +11,19 @@ export default class ListService {
}
this.api = new Request(baseURL);
}
// 获取资讯
async getArticleList(author_id, tag, gender='1,3', uid=0, page=1, limit=20, sort_id=0) {
console.log(uid);
return await this.api.get({
url: '/guang/api/v2/article/getList',
body: {
gender,
sort_id,
uid,
tag,
tag,
author_id,
page,
page,
limit,
}
})
... ... @@ -33,5 +34,36 @@ export default class ListService {
throw(error);
});
}
async setArticleFavorite(article_id, uid=0) {
return await this.api.get({
url: '/guang/api/v1/favorite/setFavorite',
body: {
article_id,
uid,
}
})
.then((json) => {
return json;
})
.catch((error) => {
throw(error);
});
}
async cancleArticleFavorite(article_id, uid=0) {
return await this.api.get({
url: '/guang/api/v1/favorite/cancelFavorite',
body: {
article_id,
uid,
}
})
.then((json) => {
return json;
})
.catch((error) => {
throw(error);
});
}
}
... ...
... ... @@ -103,7 +103,7 @@ export default function native(platform) {
let gender = this.props.genderType;
store.dispatch(setGender(gender));
}
return (
<Provider store={store}>
<PlustarContainer />
... ...
... ... @@ -25,6 +25,7 @@ export default class BrandArticleList extends Component {
this._renderRow = this._renderRow.bind(this);
this._renderHeader = this._renderHeader.bind(this);
this._renderSeparator = this._renderSeparator.bind(this);
this.dataSource = new ListView.DataSource({
rowHasChanged: (r1, r2) => !Immutable.is(r1, r2),
... ... @@ -55,12 +56,18 @@ export default class BrandArticleList extends Component {
}
_renderSeparator(sectionID, rowID, adjacentRowHighlighted) {
//最后一条记录无需Separator
if (!this.props || !this.props.articleList || (this.props.articleList.length - rowID) == 1) {
return null;
}
return (
<View key={'sep' + rowID} style={styles.separator}></View>
);
}
render() {
let {articleList} = this.props;
if (!articleList || articleList.length == 0) {
... ...
... ... @@ -36,7 +36,7 @@ export default class BrandIntro extends Component {
let titleFoldArrowIcon = brandIntro.titleUnfold ? require("../../images/arrow_small_up.png") : require("../../images/arrow_small_down.png");
return (
<View style={styles.container}>
<SlicedImage style={styles.coverImage} source={{uri: detail.cover_img}} style={{width, height:coverImageHeight}}/>
<SlicedImage style={[styles.coverImage, {width, height:coverImageHeight}]} source={{uri: detail.cover_img}}/>
<View style={styles.titleLikeView}>
... ... @@ -93,7 +93,6 @@ let styles = StyleSheet.create({
position: 'absolute',
top: 116 * DEVICE_WIDTH_RATIO,
left: 25 * DEVICE_WIDTH_RATIO,
borderWidth: 1,
height: brandIconWidth,
width: brandIconWidth,
borderWidth: 1,
... ...
'use strict'
import React, {Component} from 'react';
import ReactNative, {
StyleSheet,
Dimensions,
Platform,
View,
NativeModules,
InteractionManager,
NativeAppEventEmitter,
ListView,
} from 'react-native'
import {Map} from 'immutable';
import BrandIntro from './BrandIntro'
import BrandArticleList from './BrandArticleList'
import BrandArticleCell from './BrandArticleCell'
import NewArrival from './NewArrival'
import Prompt from '../../../coupon/components/coupon/Prompt';
export default class Detail extends React.Component{
constructor(props) {
super(props);
this.renderRow = this.renderRow.bind(this);
this.dataSource = new ListView.DataSource({
rowHasChanged: (r1, r2) => !Immutable.is(r1, r2),
sectionHeaderHasChanged: (s1, s2) => !Immutable.is(s1, s2),
});
}
componentWillReceiveProps(nextProps) {
if (this.props.detail.get('brandInfo').get('titleUnfold') && !nextProps.detail.get('brandInfo').get('titleUnfold')) {
this.listView.scrollTo({x: 0, y: 0, animated: false, });
}
}
renderRow(rowData, sectionID, rowID, highlightRow) {
if (!rowData && rowData.length == 0) {
return null;
}
switch (rowID) {
case 'brandInfo':
return(
<BrandIntro
brandIntro={rowData}
brandFav={this.props.detail.get('brandFav')}
onPressFav={this.props.onPressFav}
onPressBrandIntroMore={this.props.onPressBrandIntroMore}
addCanelFavTipRemove={this.props.addCanelFavTipRemove}
/>
);
case 'productList':
console.log(rowData);
console.log('rowData');
return (
<NewArrival
prodcutList={rowData}
onPressMoreProducts={this.props.onPressMoreProducts}
onPressProduct={this.props.onPressProduct}
moreProductUrl={this.props.detail.get('moreProductUrl')}
/>
);
case 'articleList':
return(
<BrandArticleList
articleList={rowData}
onPressArticle={this.props.onPressArticle}
onPressArticleLike={this.props.onPressArticleLike} />
);
default:
return null;
}
}
render() {
let {detail} = this.props;
let dataSource = {
brandInfo: detail.get('brandInfo'),
productList: detail.get('productList').toArray(),
articleList: detail.get('articleList').toArray(),
};
return (
<View style={styles.container}>
<ListView
ref={(c) => {
this.listView = c;
}}
contentContainerStyle={styles.contentContainer}
enableEmptySections={true}
dataSource={this.dataSource.cloneWithRows(dataSource)}
renderRow={this.renderRow}
/>
{detail.get('brandInfo').get('addCancelTip') !== '' ? <Prompt
text={detail.get('brandInfo').get('addCancelTip')}
duration={800}
onPromptHidden={this.props.addCanelFavTipRemove}
/> : null}
</View>
);
}
};
let styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f0f0f0',
},
contentContainer:{
flexDirection: 'column',
flexWrap: 'wrap',
},
});
... ...
... ... @@ -16,11 +16,7 @@ import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {Map} from 'immutable';
import * as detailActions from '../reducers/detail/detailActions';
import BrandIntro from '../components/detail/BrandIntro'
import BrandArticleList from '../components/detail/BrandArticleList'
import BrandArticleCell from '../components/detail/BrandArticleCell'
import NewArrival from '../components/detail/NewArrival'
import Prompt from '../../coupon/components/coupon/Prompt';
import Detail from '../components/detail/Detail'
const actions = [
detailActions,
... ... @@ -46,9 +42,12 @@ function mapDispatchToProps(dispatch) {
}
class DetailContainer extends Component {
componentDidMount() {
this.props.actions.getBrandInfo();
this.props.actions.uidBrandFav();
this.props.actions.brandInfo();
}
constructor(props) {
super(props);
this._onPressArticle = this._onPressArticle.bind(this);
... ... @@ -57,23 +56,7 @@ class DetailContainer extends Component {
this._onPressBrandIntroMore = this._onPressBrandIntroMore.bind(this);
this._onPressMoreProducts = this._onPressMoreProducts.bind(this);
this._addCanelFavTipRemove = this._addCanelFavTipRemove.bind(this);
this.renderRow = this.renderRow.bind(this);
this.dataSource = new ListView.DataSource({
rowHasChanged: (r1, r2) => !Immutable.is(r1, r2),
sectionHeaderHasChanged: (s1, s2) => !Immutable.is(s1, s2),
});
}
componentDidMount() {
this.props.actions.uidBrandFav();
this.props.actions.brandInfo();
}
componentWillReceiveProps(nextProps) {
if (this.props.detail.get('brandInfo').get('titleUnfold') && !nextProps.detail.get('brandInfo').get('titleUnfold')) {
this.listView.scrollTo({x: 0, y: 0, animated: false, });
}
this._onPressProduct = this._onPressProduct.bind(this);
}
_onPressArticle(url) {
... ... @@ -115,73 +98,21 @@ class DetailContainer extends Component {
this.props.actions.addCanelFavTipRemove();
}
renderRow(rowData, sectionID, rowID, highlightRow) {
if (!rowData && rowData.length == 0) {
return null;
}
switch (rowID) {
case 'brandInfo':
return(
<BrandIntro
brandIntro={rowData}
brandFav={this.props.detail.get('brandFav')}
onPressFav={this._onPressFav}
onPressBrandIntroMore={this._onPressBrandIntroMore}
addCanelFavTipRemove={this._addCanelFavTipRemove}
/>
);
case 'productList':
console.log(rowData);
console.log('rowData');
return (
<NewArrival
prodcutList={rowData}
onPressMoreProducts={this._onPressMoreProducts}
onPressProduct={this._onPressProduct}
moreProductUrl={this.props.detail.get('moreProductUrl')}
/>
);
case 'articleList':
return(
<BrandArticleList
articleList={rowData}
onPressArticle={this._onPressArticle}
onPressArticleLike={this._onPressArticleLike} />
);
default:
return null;
}
}
render() {
let {detail} = this.props;
let dataSource = {
brandInfo: detail.get('brandInfo'),
productList: detail.get('productList').toArray(),
articleList: detail.get('articleList').toArray(),
};
return (
<View style={styles.container}>
<ListView
ref={(c) => {
this.listView = c;
}}
contentContainerStyle={styles.contentContainer}
enableEmptySections={true}
dataSource={this.dataSource.cloneWithRows(dataSource)}
renderRow={this.renderRow}
<Detail
detail={detail}
onPressArticle={this._onPressArticle}
onPressArticleLike={this._onPressArticleLike}
onPressFav={this._onPressFav}
onPressBrandIntroMore={this._onPressBrandIntroMore}
onPressMoreProducts={this._onPressMoreProducts}
addCanelFavTipRemove={this._addCanelFavTipRemove}
onPressProduct={this._onPressProduct}
/>
{detail.get('brandInfo').get('addCancelTip') !== '' ? <Prompt
text={detail.get('brandInfo').get('addCancelTip')}
duration={800}
onPromptHidden={this._addCanelFavTipRemove}
/> : null}
</View>
);
}
... ...
... ... @@ -158,7 +158,7 @@ export function jumpWithUrl(url) {
}
//拼接type
url = urlAddParamOfType(url);
ReactNative.NativeModules.YH_PlustarHelper.jumpWithUrl(url);
ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url);
return {
type: JUMP_WITH_URL,
payload: url
... ...