diff --git a/js/common/components/SlicedImage.js b/js/common/components/SlicedImage.js index 768bb27..2b99a90 100644 --- a/js/common/components/SlicedImage.js +++ b/js/common/components/SlicedImage.js @@ -28,7 +28,7 @@ export default class SlicedImage extends React.Component { width = PixelRatio.getPixelSizeForLayoutSize(width); height = PixelRatio.getPixelSizeForLayoutSize(height); let newSrc = src; - if (src.indexOf('imageView2') === -1) { + if (src.indexOf('imageView') === -1) { newSrc = src + '?imageView2/' + this.mode + '/w/' + width + '/h/' + height; } else { newSrc = src.replace('{mode}', this.mode) diff --git a/js/community/Community.js b/js/community/Community.js index b2416e1..7b85935 100644 --- a/js/community/Community.js +++ b/js/community/Community.js @@ -317,8 +317,7 @@ export default function community(platform) { }, homeOnRight(state) { - Actions.SubjectPost(); - // state.dispatch(startEditPost(state.getPostingState())); + state.dispatch(startEditPost(state.getPostingState())); }, pushPostingWithUID(uid) { diff --git a/js/community/components/home/Home.js b/js/community/components/home/Home.js index c404217..67ce8ed 100644 --- a/js/community/components/home/Home.js +++ b/js/community/components/home/Home.js @@ -307,7 +307,7 @@ export default class Home extends React.Component { isVisible={isSyncFetching} /> <SuperMan - fly={styles.fly} + uid={user.uid} avatar={user.avatar} msgCount={user.msgCount} onSaveingTheWorld={this.props.onSaveingTheWorld} @@ -355,9 +355,4 @@ let styles = StyleSheet.create({ height: 0.5, backgroundColor: '#e0e0e0', }, - fly: { - position: 'absolute', - right: 20, - bottom: 20, - }, }); diff --git a/js/community/components/home/NumberButton.js b/js/community/components/home/NumberButton.js index 410f796..0cca13d 100644 --- a/js/community/components/home/NumberButton.js +++ b/js/community/components/home/NumberButton.js @@ -51,6 +51,7 @@ let styles = StyleSheet.create({ height: 18, }, number: { + color: '#b0b0b0', fontSize: 14, marginLeft: 5, }, diff --git a/js/community/components/home/SuperMan.js b/js/community/components/home/SuperMan.js index efba8fb..a6d4f37 100644 --- a/js/community/components/home/SuperMan.js +++ b/js/community/components/home/SuperMan.js @@ -17,6 +17,7 @@ const { export default class SuperMan extends React.Component { static propTypes = { + uid: React.PropTypes.number, avatar: React.PropTypes.string, msgCount: React.PropTypes.string, onSaveingTheWorld: React.PropTypes.func, @@ -28,8 +29,18 @@ export default class SuperMan extends React.Component { } + renderText() { + if (this.props.uid == 0 ) { + return ( + <Text style={styles.loginText}>请登录</Text> + ); + } else { + return null; + } + } + renderMsgCount() { - if (parseInt(this.props.msgCount) !== 0) { + if (this.props.uid > 0 && parseInt(this.props.msgCount) !== 0) { return ( <View style={styles.textContainer}> <Text style={styles.text}>{this.props.msgCount}</Text> @@ -41,15 +52,17 @@ export default class SuperMan extends React.Component { } render() { - let avtatStyle = this.props.avatar ? styles.avatarContainer : null; + let avatarContainerStyle = this.props.uid > 0 ? styles.avatarContainer : null; + let avatarStyle = this.props.uid > 0 ? styles.avatarBorder : null; return ( <View style={[styles.container, this.props.fly]}> <TouchableOpacity activeOpacity={0.8} onPress={() => { this.props.onSaveingTheWorld && this.props.onSaveingTheWorld(); }}> - <View style={avtatStyle}> - <SlicedImage style={styles.avatar} source={{uri: this.props.avatar}} resizeMode={'cover'} defaultSource={require('../../images/home/superman.png')}/> + <View style={avatarContainerStyle}> + <SlicedImage style={[styles.avatar, avatarStyle]} source={{uri: this.props.avatar}} resizeMode={'cover'} defaultSource={require('../../images/home/superman.png')}/> </View> + {this.renderText()} {this.renderMsgCount()} </TouchableOpacity> </View> @@ -59,7 +72,10 @@ export default class SuperMan extends React.Component { let styles = StyleSheet.create({ container: { - flexDirection: 'row', + position: 'absolute', + right: 20, + bottom: 20, + flexDirection: 'column', alignItems: 'center', backgroundColor: 'transparent', width: 45, @@ -79,12 +95,15 @@ let styles = StyleSheet.create({ width: 44, height: 44, borderRadius: 22, + }, + avatarBorder: { borderColor: 'white', borderWidth: 1, - // shadowColor: 'red', - // shadowOpacity: 1, - // // shadowRadius: 20, - // shadowOffset: {width: 0, height: 0}, + }, + loginText: { + marginTop: 2, + fontSize: 10, + textAlign: 'center', }, textContainer: { position: 'absolute', diff --git a/js/community/components/section/Section.js b/js/community/components/section/Section.js index 75c78e2..81cd06a 100644 --- a/js/community/components/section/Section.js +++ b/js/community/components/section/Section.js @@ -290,7 +290,7 @@ export default class Section extends React.Component { }} /> <SuperMan - fly={styles.fly} + uid={user.uid} avatar={user.avatar} msgCount={user.msgCount} onSaveingTheWorld={this.props.onSaveingTheWorld} diff --git a/js/community/components/section/SectionHeader.js b/js/community/components/section/SectionHeader.js index 63620e0..9edd2df 100644 --- a/js/community/components/section/SectionHeader.js +++ b/js/community/components/section/SectionHeader.js @@ -22,7 +22,8 @@ export default class SectionHeader extends React.Component { static propTypes = { data: ImmutablePropTypes.contains({ uri: React.PropTypes.string.isRequired, - title: React.PropTypes.string.isRequired, + title: React.PropTypes.string, + desc: React.PropTypes.string.isRequired, post: React.PropTypes.string.isRequired, comment: React.PropTypes.string.isRequired, like: React.PropTypes.string.isRequired, @@ -35,11 +36,11 @@ export default class SectionHeader extends React.Component { } render() { - let {uri, title, post, comment, like} = this.props.data.toJS(); + let {uri, desc, post, comment, like} = this.props.data.toJS(); return ( <Image style={[styles.container, this.props.style]} source={{uri}} resizeMode={'cover'}> - <Text style={styles.title}>{title}</Text> - <View style={styles.desc}> + <Text style={styles.desc}>{desc}</Text> + <View style={styles.stats}> <Text style={[styles.content, {flex: 0.3}]} numberOfLines={1}>{post}</Text> <Text style={styles.content}>|</Text> <Text style={[styles.content, {flex: 0.3}]} numberOfLines={1}>{comment}</Text> @@ -58,7 +59,7 @@ let styles = StyleSheet.create({ // alignItems: 'center', backgroundColor: '#b0b0b0', }, - title: { + desc: { color: 'white', // fontFamily: 'SourceHanSansCN Normal', fontSize: 24, @@ -66,7 +67,7 @@ let styles = StyleSheet.create({ textAlign: 'center', backgroundColor: 'transparent', }, - desc: { + stats: { flex: 1, flexDirection: 'row', justifyContent: 'space-between', diff --git a/js/community/constants/actionTypes.js b/js/community/constants/actionTypes.js index 72bf165..fa97ba2 100755 --- a/js/community/constants/actionTypes.js +++ b/js/community/constants/actionTypes.js @@ -5,6 +5,7 @@ export default keyMirror({ SET_PLATFORM: null, SET_CONTAINER: null, SET_CHANNEL: null, + GO_ACTION: null, SET_UID: null, SYNC_USER_REQUEST: null, @@ -52,7 +53,7 @@ export default keyMirror({ /*用户中心*/ USER_BACKGROUND_TAP: null, - USER_AVATAR_TAP:null, + USER_AVATAR_TAP: null, USER_POSTS_REQUEST: null, //我的帖子 USER_POSTS_SUCCESS: null, diff --git a/js/community/containers/HomeContainer.js b/js/community/containers/HomeContainer.js index e76d100..fd7eb01 100644 --- a/js/community/containers/HomeContainer.js +++ b/js/community/containers/HomeContainer.js @@ -117,11 +117,12 @@ class HomeContainer extends React.Component { } _onPressBanner(url) { - ReactNative.NativeModules.YH_CommunityHelper.jumpWithUrl(url, {}); + this.props.actions.goAction(url); } _onPressNotice(url) { - ReactNative.NativeModules.YH_CommunityHelper.jumpWithUrl(url, {}); + // url = `http://feature.yoho.cn/0714/0714ITEMBOY/index.html?title=男生分会场&share_id=814&openby:yohobuy={"action":"go.comm.h5","params":{"product_skn":51285070,"forumid":10003,"param":{"share_id":"814","title":"男生分会场"},"share":"/operations/api/v5/webshare/getShare","shareparam":{"share_id":"814"},"title":"男生分会场","url":"http://feature.yoho.cn/0714/0714ITEMBOY/index.html"}}`; + this.props.actions.goAction(url); } _onPressSection(section) { diff --git a/js/community/containers/SectionContainer.js b/js/community/containers/SectionContainer.js index 488c928..2dc977f 100644 --- a/js/community/containers/SectionContainer.js +++ b/js/community/containers/SectionContainer.js @@ -13,6 +13,7 @@ import Section from '../components/section/Section'; import * as sectionActions from '../reducers/section/sectionActions'; import * as postingActions from '../reducers/posting/postingActions'; import * as homeActions from '../reducers/home/homeActions'; +import * as appActions from '../reducers/app/appActions'; import {Actions} from 'react-native-router-flux'; import {shouldShowTabBar, shouldHideTabBar} from '../utils/tabBar'; @@ -32,7 +33,8 @@ const { const actions = [ sectionActions, postingActions, - homeActions + homeActions, + appActions ]; /** @@ -98,12 +100,11 @@ class SectionContainer extends React.Component { } _onPressBanner(url) { - console.log('banner'); - + this.props.actions.goAction(url); } _onPressNotice(url) { - console.log('notice'); + this.props.actions.goAction(url); } _onPressPost(id) { diff --git a/js/community/reducers/app/appActions.js b/js/community/reducers/app/appActions.js index 3fc41b0..c075dc2 100755 --- a/js/community/reducers/app/appActions.js +++ b/js/community/reducers/app/appActions.js @@ -6,13 +6,17 @@ */ 'use strict'; +import ReactNative from 'react-native'; import {Actions} from 'react-native-router-flux'; import AppService from '../../services/AppService'; +import RouterService from '../../services/RouterService'; +import {goToSection, goToPost} from '../home/homeActions'; const { SET_PLATFORM, SET_CONTAINER, SET_CHANNEL, + GO_ACTION, } = require('../../constants/actionTypes').default; export function setPlatform(platform) { @@ -35,3 +39,46 @@ export function setChannel(channel) { payload: channel }; } + +export function goAction(inputUrl) { + return (dispatch, getState) => { + return new RouterService().parseUrl(inputUrl) + .then((json) => { + let {action, params} = json; + let {param, share, shareparam, title, url} = params; + + if (action == 'go.comm.forum') { + let id = params && params.forumid ? params.forumid : 0; + let name = ''; + if (id != 0) { + dispatch(goToSection({id, name})); + } + + } else if (action == 'go.comm.postdetail') { + let id = params && params.postid ? params.postid : 0; + if (id != 0) { + dispatch(goToPost(id)); + } + + } else if (action == 'go.comm.h5') { + let title = params.title ? params.title : ''; + let url = params.url ? params.url : ''; + if (!url || url.length == 0) { + return; + } + ReactNative.NativeModules.YH_CommunityHelper.displayH5({url, title}); + } else if (action == 'go.comm.productDetail') { + let productSkn = params.product_skn ? params.product_skn : ''; + productSkn = productSkn + ''; + let tag = params.tag ? params.tag : ''; + if (!productSkn || productSkn.length == 0) { + return; + } + ReactNative.NativeModules.YH_CommunityHelper.displayProductDetail({productSkn, tag}); + } + }) + .catch(error => { + __DEV__ && console.log(error); + }); + }; +} diff --git a/js/community/reducers/home/homeActions.js b/js/community/reducers/home/homeActions.js index 5574f2b..492ce00 100755 --- a/js/community/reducers/home/homeActions.js +++ b/js/community/reducers/home/homeActions.js @@ -69,7 +69,7 @@ export function goToUserOrMe(uid) { } export function goToPost(id) { - // Actions.Post(); + Actions.SubjectPost(); return { type: GO_TO_POST, payload: id, @@ -322,6 +322,7 @@ function parseBNS(json) { id: item.forumCode ? item.forumCode : 0, logo: item.forumPic ? item.forumPic : '', title: item.forumName ? item.forumName : '', + desc: item.forumDesc ? item.forumDesc : '', post: number10KFormater(item.postsNum), comment: number10KFormater(item.commentsNum), like: number10KFormater(item.praiseNum), diff --git a/js/community/reducers/section/sectionActions.js b/js/community/reducers/section/sectionActions.js index 7f46d91..187dd68 100755 --- a/js/community/reducers/section/sectionActions.js +++ b/js/community/reducers/section/sectionActions.js @@ -232,6 +232,7 @@ function parseHeader(json) { let uri = json.forumPic ? json.forumPic : ''; let title = json.forumName ? json.forumName : ''; + let desc = json.forumDesc ? json.forumDesc : ''; let post = number10KFormater(json.postsNum); let comment = number10KFormater(json.commentsNum); let like = number10KFormater(json.praiseNum); @@ -239,6 +240,7 @@ function parseHeader(json) { let header = { uri, title, + desc, post, comment, like, diff --git a/js/community/reducers/section/sectionInitialState.js b/js/community/reducers/section/sectionInitialState.js index dc1652b..45a40b9 100755 --- a/js/community/reducers/section/sectionInitialState.js +++ b/js/community/reducers/section/sectionInitialState.js @@ -29,6 +29,7 @@ let item = new (Record({ header: new (Record({ uri: '', title: '', + desc: '', post: '', comment: '', like: '', diff --git a/js/community/reducers/section/sectionReducer.js b/js/community/reducers/section/sectionReducer.js index d0aed61..6136a4a 100755 --- a/js/community/reducers/section/sectionReducer.js +++ b/js/community/reducers/section/sectionReducer.js @@ -76,6 +76,7 @@ export default function sectionReducer(state = initialState, action) { .set('ptr', false) .setIn(['header', 'uri'], header.uri) .setIn(['header', 'title'], header.title) + .setIn(['header', 'desc'], header.desc) .setIn(['header', 'post'], header.post) .setIn(['header', 'comment'], header.comment) .setIn(['header', 'like'], header.like) diff --git a/js/community/reducers/subject/subjectPostReducer.js b/js/community/reducers/subject/subjectPostReducer.js index c4fae39..94ff1d1 100644 --- a/js/community/reducers/subject/subjectPostReducer.js +++ b/js/community/reducers/subject/subjectPostReducer.js @@ -13,6 +13,8 @@ import InitialState from './subjectPostInitialState'; import Immutable, {List, Record} from 'immutable'; const { + GO_TO_POST, + SUBJECT_CONTENT_REQUEST, SUBJECT_CONTENT_SUCCESS, SUBJECT_CONTENT_FAILURE, @@ -34,6 +36,10 @@ export default function postingReducer(state = initialState, action) { if (!(state instanceof InitialState)) return initialState.merge(state); switch (action.type) { + case GO_TO_POST: { + return state.set('id', action.payload); + } + case SUBJECT_CONTENT_REQUEST: { let nextState = state.set('isContentFetching', true).set('contentError', null); return nextState; diff --git a/js/community/services/RouterService.js b/js/community/services/RouterService.js index 02dd439..5c81d1d 100644 --- a/js/community/services/RouterService.js +++ b/js/community/services/RouterService.js @@ -8,5 +8,35 @@ export default class RouterService { this.api = new Request(); } - + parseUrl(url) { + return new Promise((resolve, reject) => { + if (!url) { + reject('Illegal url: ' + url); + } + + // url解码 + url = decodeURI(url); + // 处理半角等号和全角等号 + let mark = 'yohobuy='; + let markIndex = url.indexOf(mark); + if (markIndex == -1) { + mark = 'yohobuy='; + markIndex = url.indexOf(mark); + } + + if (markIndex == -1) { + reject('Can not find url rule: ' + url); + } + + let rule = url.substring(markIndex + mark.length); + + let json; + try { + json = JSON.parse(rule); + resolve(json); + } catch (e) { + reject('Parse json string fail: ' + e); + } + }); + } }