├── .watchmanconfig ├── test ├── reducers │ └── home.js ├── web.js ├── views │ └── home.js ├── reduxApp.js ├── app.js └── store │ └── configureStore.js ├── js ├── services │ ├── merchantService.js │ ├── token.js │ ├── albumService.js │ ├── homeService.js │ ├── storage.js │ └── request.js ├── actions │ ├── albumDetail.js │ ├── merchantDetail.js │ ├── index.js │ ├── home.js │ ├── album.js │ └── merchant.js ├── data │ ├── sortBys.js │ ├── areas.js │ └── categories.js ├── reducers │ ├── albumDetail.js │ ├── merchantDetail.js │ ├── index.js │ ├── album.js │ ├── merchant.js │ └── home.js ├── constants │ ├── HttpUrls.js │ └── ActionTypes.js ├── root.js ├── store │ └── configureStore.js ├── svg │ ├── Back.js │ ├── Stars.js │ ├── Logo.js │ └── FaceIcon.js ├── detail │ ├── AblumDetailView.js │ └── ActivityDetailView.js ├── views │ ├── FilterView.js │ ├── FilterHeaderView.js │ └── MerchantDetail.js ├── common │ ├── SectionHeaderView.js │ ├── CommonCell.js │ ├── Img.js │ ├── NavigatorHeader.js │ ├── Checker.js │ └── SplitView.js ├── components │ ├── DetailHeader.js │ ├── ChannelSvgButton.js │ └── Channels.js ├── Cell │ ├── MerchantDetailCell.js │ ├── MerchantCell.js │ ├── AlbumCell.js │ └── ActivityCell.js ├── tabs │ ├── Album.js │ ├── Merchant.js │ └── Home.js └── marry.js ├── android ├── settings.gradle ├── app │ ├── src │ │ └── main │ │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ └── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── com │ │ │ └── marry │ │ │ └── MainActivity.java │ ├── BUCK │ ├── proguard-rules.pro │ └── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── keystores │ ├── debug.keystore.properties │ └── BUCK ├── build.gradle ├── gradle.properties ├── gradlew.bat └── gradlew ├── Img ├── qq.png ├── 10086.png ├── 12306.png ├── aibang.png ├── baidu.png ├── ifeng.png ├── mart.png ├── martB.png ├── mlogo.png ├── news.png ├── quecai.png ├── qunar.png ├── sina.png ├── sohu.png ├── taobao.png ├── tmall.png ├── wcar.png ├── weibo.png ├── baidumap.png ├── magnify.png ├── taobaoc.png ├── kuaidi100.png ├── recreation.png └── weathercn.png ├── images ├── 404.png ├── 404@2x.png ├── 404@3x.png ├── loading.gif ├── loading@2x.gif └── loading@3x.gif ├── screenshot ├── home.png ├── album.png ├── merchant.png └── marry_0614.gif ├── ios ├── Marry │ ├── Images.xcassets │ │ ├── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── AppIcon29x29@2x.png │ │ │ ├── AppIcon29x29@3x.png │ │ │ ├── AppIcon40x40@2x.png │ │ │ ├── AppIcon40x40@3x.png │ │ │ ├── AppIcon60x60@2x.png │ │ │ ├── AppIcon60x60@3x.png │ │ │ └── Contents.json │ │ ├── LaunchImage.launchimage │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage-700@2x.png │ │ │ ├── LaunchImage-700-568h@2x.png │ │ │ ├── LaunchImage-800-667h@2x.png │ │ │ ├── LaunchImage-800-Portrait-736h@3x.png │ │ │ └── Contents.json │ │ └── Brand Assets.launchimage │ │ │ └── Contents.json │ ├── AppDelegate.h │ ├── main.m │ ├── Info.plist │ ├── AppDelegate.m │ └── Base.lproj │ │ └── LaunchScreen.xib └── MarryTests │ ├── Info.plist │ └── MarryTests.m ├── .buckconfig ├── HourglassLoading.js ├── .gitignore ├── package.json ├── index.ios.js ├── app.js ├── README.md ├── index.android.js ├── webdetail.js ├── .flowconfig └── webcell.js /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /test/reducers/home.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /js/services/merchantService.js: -------------------------------------------------------------------------------- 1 | // merchantService.js -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Marry' 2 | 3 | include ':app' 4 | -------------------------------------------------------------------------------- /Img/qq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/qq.png -------------------------------------------------------------------------------- /Img/10086.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/10086.png -------------------------------------------------------------------------------- /Img/12306.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/12306.png -------------------------------------------------------------------------------- /Img/aibang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/aibang.png -------------------------------------------------------------------------------- /Img/baidu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/baidu.png -------------------------------------------------------------------------------- /Img/ifeng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/ifeng.png -------------------------------------------------------------------------------- /Img/mart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/mart.png -------------------------------------------------------------------------------- /Img/martB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/martB.png -------------------------------------------------------------------------------- /Img/mlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/mlogo.png -------------------------------------------------------------------------------- /Img/news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/news.png -------------------------------------------------------------------------------- /Img/quecai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/quecai.png -------------------------------------------------------------------------------- /Img/qunar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/qunar.png -------------------------------------------------------------------------------- /Img/sina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/sina.png -------------------------------------------------------------------------------- /Img/sohu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/sohu.png -------------------------------------------------------------------------------- /Img/taobao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/taobao.png -------------------------------------------------------------------------------- /Img/tmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/tmall.png -------------------------------------------------------------------------------- /Img/wcar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/wcar.png -------------------------------------------------------------------------------- /Img/weibo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/weibo.png -------------------------------------------------------------------------------- /images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/images/404.png -------------------------------------------------------------------------------- /Img/baidumap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/baidumap.png -------------------------------------------------------------------------------- /Img/magnify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/magnify.png -------------------------------------------------------------------------------- /Img/taobaoc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/taobaoc.png -------------------------------------------------------------------------------- /Img/kuaidi100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/kuaidi100.png -------------------------------------------------------------------------------- /Img/recreation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/recreation.png -------------------------------------------------------------------------------- /Img/weathercn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/Img/weathercn.png -------------------------------------------------------------------------------- /images/404@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/images/404@2x.png -------------------------------------------------------------------------------- /images/404@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/images/404@3x.png -------------------------------------------------------------------------------- /images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/images/loading.gif -------------------------------------------------------------------------------- /screenshot/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/screenshot/home.png -------------------------------------------------------------------------------- /images/loading@2x.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/images/loading@2x.gif -------------------------------------------------------------------------------- /images/loading@3x.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/images/loading@3x.gif -------------------------------------------------------------------------------- /screenshot/album.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/screenshot/album.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Marry 3 | 4 | -------------------------------------------------------------------------------- /ios/Marry/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /screenshot/merchant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/screenshot/merchant.png -------------------------------------------------------------------------------- /screenshot/marry_0614.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/screenshot/marry_0614.gif -------------------------------------------------------------------------------- /.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /js/actions/albumDetail.js: -------------------------------------------------------------------------------- 1 | // albumDetail.js 2 | import {createAction} from 'redux-actions'; 3 | import * as ActionTypes from "../constants/ActionTypes"; -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /js/actions/merchantDetail.js: -------------------------------------------------------------------------------- 1 | // merchantDetail.js 2 | import {createAction} from 'redux-actions'; 3 | import * as ActionTypes from "../constants/ActionTypes"; -------------------------------------------------------------------------------- /android/keystores/debug.keystore.properties: -------------------------------------------------------------------------------- 1 | key.store=debug.keystore 2 | key.alias=androiddebugkey 3 | key.store.password=android 4 | key.alias.password=android 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /js/services/token.js: -------------------------------------------------------------------------------- 1 | // token.js 2 | 3 | export const getToken = ()=>{ 4 | return global.token; 5 | } 6 | 7 | export const setToken = (token)=>{ 8 | global.token = token; 9 | } -------------------------------------------------------------------------------- /test/web.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import ReactNative, { 3 | Navigator, 4 | View, 5 | ListView, 6 | Text, 7 | Image 8 | } from 'react-native'; 9 | -------------------------------------------------------------------------------- /android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = 'debug', 3 | store = 'debug.keystore', 4 | properties = 'debug.keystore.properties', 5 | visibility = [ 6 | 'PUBLIC', 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /ios/Marry/Images.xcassets/AppIcon.appiconset/AppIcon29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/ios/Marry/Images.xcassets/AppIcon.appiconset/AppIcon29x29@2x.png -------------------------------------------------------------------------------- /ios/Marry/Images.xcassets/AppIcon.appiconset/AppIcon29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/ios/Marry/Images.xcassets/AppIcon.appiconset/AppIcon29x29@3x.png -------------------------------------------------------------------------------- /ios/Marry/Images.xcassets/AppIcon.appiconset/AppIcon40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/ios/Marry/Images.xcassets/AppIcon.appiconset/AppIcon40x40@2x.png -------------------------------------------------------------------------------- /ios/Marry/Images.xcassets/AppIcon.appiconset/AppIcon40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/ios/Marry/Images.xcassets/AppIcon.appiconset/AppIcon40x40@3x.png -------------------------------------------------------------------------------- /ios/Marry/Images.xcassets/AppIcon.appiconset/AppIcon60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/ios/Marry/Images.xcassets/AppIcon.appiconset/AppIcon60x60@2x.png -------------------------------------------------------------------------------- /ios/Marry/Images.xcassets/AppIcon.appiconset/AppIcon60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/ios/Marry/Images.xcassets/AppIcon.appiconset/AppIcon60x60@3x.png -------------------------------------------------------------------------------- /ios/Marry/Images.xcassets/LaunchImage.launchimage/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/ios/Marry/Images.xcassets/LaunchImage.launchimage/LaunchImage.png -------------------------------------------------------------------------------- /ios/Marry/Images.xcassets/LaunchImage.launchimage/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/ios/Marry/Images.xcassets/LaunchImage.launchimage/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Marry/Images.xcassets/LaunchImage.launchimage/LaunchImage-700@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/ios/Marry/Images.xcassets/LaunchImage.launchimage/LaunchImage-700@2x.png -------------------------------------------------------------------------------- /ios/Marry/Images.xcassets/LaunchImage.launchimage/LaunchImage-700-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/ios/Marry/Images.xcassets/LaunchImage.launchimage/LaunchImage-700-568h@2x.png -------------------------------------------------------------------------------- /ios/Marry/Images.xcassets/LaunchImage.launchimage/LaunchImage-800-667h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/ios/Marry/Images.xcassets/LaunchImage.launchimage/LaunchImage-800-667h@2x.png -------------------------------------------------------------------------------- /js/data/sortBys.js: -------------------------------------------------------------------------------- 1 | export const SortBys = [ 2 | {title:"默认",id:1}, 3 | {title:"更新日期",id:2}, 4 | {title:"收藏人气",id:3}, 5 | {title:"点赞数",id:4} 6 | ]; 7 | export const defaultId = 1; 8 | export const defaultTitle = "默认排序"; 9 | -------------------------------------------------------------------------------- /ios/Marry/Images.xcassets/LaunchImage.launchimage/LaunchImage-800-Portrait-736h@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zqmReactNative/react-native-redux-marry/HEAD/ios/Marry/Images.xcassets/LaunchImage.launchimage/LaunchImage-800-Portrait-736h@3x.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip 6 | -------------------------------------------------------------------------------- /test/views/home.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import ReactNative, { 3 | View, 4 | ListView, 5 | Text, 6 | Image, 7 | } from 'react-native'; 8 | 9 | export default class Home extends Component { 10 | render() { 11 | return ( 12 | 13 | 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /js/reducers/albumDetail.js: -------------------------------------------------------------------------------- 1 | // albumDetail.js 2 | // AlbumDetail Reducer 3 | 4 | import * as types from "../constants/ActionTypes"; 5 | const initialState = {}; 6 | 7 | export default function (state = initialState, action) { 8 | const { type } = action; 9 | switch (type) 10 | { 11 | default: 12 | return state; 13 | } 14 | } -------------------------------------------------------------------------------- /js/reducers/merchantDetail.js: -------------------------------------------------------------------------------- 1 | // merchantDetail.js 2 | // MerchantDetail Reducer 3 | 4 | import * as types from "../constants/ActionTypes"; 5 | const initialState = {}; 6 | 7 | export default function (state = initialState, action) { 8 | const { type } = action; 9 | switch (type) 10 | { 11 | default: 12 | return state; 13 | } 14 | } -------------------------------------------------------------------------------- /js/constants/HttpUrls.js: -------------------------------------------------------------------------------- 1 | export const kHomeUrl = "http://newapi.deyi.com/wedding/api/index"; 2 | 3 | export const kAlbumUrl = "http://newapi.deyi.com/wedding/api/caselist"; 4 | 5 | export const kMerchantUrl = "http://newapi.deyi.com/wedding/api/shoplist"; 6 | 7 | // {"catid": 366} 8 | export const kHotcasesUrl = "http://newapi.deyi.com/wedding/api/hotcases"; 9 | -------------------------------------------------------------------------------- /js/data/areas.js: -------------------------------------------------------------------------------- 1 | export const Areas = [ 2 | {title:"全部",id:0}, 3 | {title:"江汉区",id:2701}, 4 | {title:"江岸区",id:2702}, 5 | {title:"硚口区",id:2703}, 6 | {title:"汉阳区",id:2707}, 7 | {title:"武昌区",id:2704}, 8 | {title:"洪山区",id:2705}, 9 | {title:"青山区",id:2706}, 10 | {title:"其他",id:2708} 11 | ]; 12 | export const defaultId = 0; 13 | export const defaultTitle = "全部地区"; 14 | -------------------------------------------------------------------------------- /js/actions/index.js: -------------------------------------------------------------------------------- 1 | // index.js 2 | 3 | import * as home from './home'; 4 | import * as album from './album'; 5 | import * as merchant from './merchant'; 6 | // import * as ablumDetail from './ablumDetail'; 7 | // import * as merchantDetail from './merchantDetail'; 8 | 9 | export default { 10 | ...home, 11 | ...album, 12 | ...merchant, 13 | // ...ablumDetail, 14 | // ...merchantDetail, 15 | }; 16 | -------------------------------------------------------------------------------- /js/services/albumService.js: -------------------------------------------------------------------------------- 1 | // albumService.js 2 | 3 | import * as requestService from './request'; 4 | import { getToken, setToken } from './token'; 5 | 6 | export function getXXXX(argument) { 7 | // body... 8 | let body = { 9 | 10 | }; 11 | let url = `http://newapi.deyi.com/wedding/api/hotcases`; 12 | return requestService.get(url) 13 | .then(filterData) 14 | .then(data=>{ 15 | 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /js/reducers/index.js: -------------------------------------------------------------------------------- 1 | // index.js 2 | import { combineReducers } from 'redux'; 3 | import home from './home'; 4 | import album from './album'; 5 | import merchant from './merchant'; 6 | import albumDetail from './albumDetail'; 7 | import merchantDetail from './merchantDetail'; 8 | 9 | export default rootReducer = combineReducers({ 10 | home, 11 | album, 12 | merchant, 13 | albumDetail, 14 | merchantDetail, 15 | }); 16 | -------------------------------------------------------------------------------- /test/reduxApp.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | import { Provider } from 'react-redux' 4 | import configureStore from './store/configureStore' 5 | 6 | import App from './app' 7 | 8 | const store = configureStore() 9 | 10 | export default class ReduxApp extends Component { 11 | render() { 12 | return ( 13 | 14 | 15 | 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /js/services/homeService.js: -------------------------------------------------------------------------------- 1 | // homeService.js 2 | 3 | import * as requestService from './request'; 4 | import { getToken, setToken } from './token'; 5 | 6 | export function getXXXX(argument) { 7 | // body... 8 | let body = { 9 | 10 | }; 11 | let url = `http://newapi.deyi.com/wedding/api/index`; 12 | return requestService.get(url) 13 | .then((response)=>response.json()) 14 | .then((responseData)=>{ 15 | return responseData 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /js/root.js: -------------------------------------------------------------------------------- 1 | import React, { 2 | Component 3 | } from 'react'; 4 | 5 | import { Provider } from 'react-redux'; 6 | import configureStore from './store/configureStore'; 7 | 8 | import Marry from './marry'; 9 | 10 | 11 | const store = configureStore(); 12 | 13 | export default class Root extends Component { 14 | render() { 15 | return ( 16 | 17 | 18 | 19 | ) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /HourglassLoading.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { PixleRatio } from 'react-native'; 3 | import Svg, { 4 | Circle, 5 | G, 6 | Path, 7 | Polygon, 8 | Rect, 9 | } from 'react-native-svg'; 10 | 11 | export default class HourglassLoading extends Component { 12 | 13 | render() { 14 | return ( 15 | 16 | 17 | 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /js/store/configureStore.js: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware } from 'redux'; 2 | import thunkMiddleware from 'redux-thunk'; 3 | import rootReducer from '../reducers'; 4 | 5 | const middlewares = [ 6 | thunkMiddleware, 7 | ]; 8 | 9 | const createStoreWithMiddleware = applyMiddleware(...middlewares)(createStore); 10 | 11 | export default function configureStore(initialStore) { 12 | const store = createStoreWithMiddleware(rootReducer, initialStore); 13 | return store; 14 | } 15 | -------------------------------------------------------------------------------- /js/svg/Back.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | import Svg, { 4 | Circle, 5 | G, 6 | Path, 7 | Polygon, 8 | } from 'react-native-svg'; 9 | 10 | export default class Back extends Component { 11 | render(){ 12 | return ( 13 | 14 | 15 | 16 | 17 | 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ios/Marry/Images.xcassets/Brand Assets.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "minimum-system-version" : "7.0", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "orientation" : "portrait", 11 | "idiom" : "iphone", 12 | "minimum-system-version" : "7.0", 13 | "subtype" : "retina4", 14 | "scale" : "2x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /ios/Marry/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (nonatomic, strong) UIWindow *window; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /js/detail/AblumDetailView.js: -------------------------------------------------------------------------------- 1 | // AblumDetailView.js 2 | // 图库详情 3 | 4 | import React, { Component, PropTypes } from "react"; 5 | 6 | import { View, Text, Image, StyleSheet, Dimensions, ListView, TouchableOpacity, TouchableHighlight } from "react-native"; 7 | import Img from '../common/Img'; 8 | const screenWidth = Dimensions.get('window').width; 9 | const screenHeight = Dimensions.get('window').height; 10 | 11 | export default class AlbumDetailView extends Component { 12 | render() { 13 | return ( 14 | 15 | 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ios/Marry/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | #import "AppDelegate.h" 13 | 14 | int main(int argc, char * argv[]) { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/app.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | import ReactNative, { 4 | View, 5 | ListView, 6 | Text, 7 | Image, 8 | StyleSheet 9 | } from 'react-native' 10 | 11 | export default class App extends Component { 12 | _renderRow = (rowData)=>{ 13 | return ( 14 | 15 | 16 | {rowData.title} 17 | 18 | 19 | ); 20 | } 21 | render() { 22 | 23 | 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IJ 26 | # 27 | .idea 28 | .gradle 29 | local.properties 30 | 31 | # node.js 32 | # 33 | node_modules/ 34 | npm-debug.log 35 | 36 | # BUCK 37 | buck-out/ 38 | \.buckd/ 39 | android/app/libs 40 | android/keystores/debug.keystore 41 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:1.3.1' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | mavenLocal() 18 | jcenter() 19 | maven { 20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 21 | url "$projectDir/../../node_modules/react-native/android" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Marry", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "node node_modules/react-native/local-cli/cli.js start" 7 | }, 8 | "dependencies": { 9 | "normalizr": "^2.0.1", 10 | "query-string": "^4.2.1", 11 | "react": "^0.14.8", 12 | "react-native": "^0.24.1", 13 | "react-native-scrollable-tab-view": "^0.4.1", 14 | "react-native-svg": "^1.0.1", 15 | "react-native-tab-navigator": "^0.2.18", 16 | "react-redux": "^4.4.5", 17 | "redux": "^3.5.1", 18 | "redux-actions": "^0.9.1", 19 | "redux-logger": "^2.6.1", 20 | "redux-promise": "^0.5.3", 21 | "redux-thunk": "^2.0.1" 22 | }, 23 | "devDependencies": { 24 | "redux-devtools": "^3.2.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /index.ios.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { 8 | Component 9 | } from 'react'; 10 | 11 | import { 12 | AppRegistry, 13 | Dimensions, 14 | StyleSheet, 15 | Text, 16 | Image, 17 | View, 18 | ListView 19 | } from 'react-native'; 20 | 21 | const kViewHeight = 50 22 | const kMarginTop = 3 23 | const screenWidth = Dimensions.get('window').width; 24 | const screenHeight = Dimensions.get('window').height; 25 | 26 | 27 | // import App from './app'; 28 | // AppRegistry.registerComponent('Marry', () => App); 29 | 30 | // import Marry from './js/marry'; 31 | // AppRegistry.registerComponent('Marry', () => Marry); 32 | 33 | import Root from './js/root'; 34 | AppRegistry.registerComponent('Marry', () => Root); 35 | -------------------------------------------------------------------------------- /ios/MarryTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /js/views/FilterView.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { ScrollView, View, Text, Image, StyleSheet, RefreshControl, TouchableOpacity, PixelRatio } from "react-native"; 3 | 4 | 5 | export default class FilterView extends Component { 6 | render() { 7 | return ( 8 | 9 | 10 | 11 | 12 | 13 | ); 14 | } 15 | } 16 | 17 | const styles = StyleSheet.create({ 18 | container: { 19 | height: 39, 20 | flexDirection: 'row', 21 | borderBottomColor: '#ccc', 22 | borderBottomWidth: 1/PixelRatio.get(), 23 | }, 24 | button: { 25 | flex: 1, 26 | alignItems: 'center', 27 | justifyContent: 'center', 28 | backgroundColor: 'red', 29 | }, 30 | dividerLine: { 31 | // marginTop: 5, 32 | // marginBottom: 5, 33 | height: 1/PixelRatio.get(), 34 | }, 35 | }); 36 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | android.useDeprecatedNdk=true 21 | -------------------------------------------------------------------------------- /js/services/storage.js: -------------------------------------------------------------------------------- 1 | // storage.js 2 | 3 | import { AsyncStorage } from 'react-native'; 4 | 5 | export const clear = AsyncStorage.clear; 6 | 7 | export async function setItem(key, value) { 8 | if (value == null) return Promise.reject('StorageService Error: value should not be null or undefined'); 9 | return await AsyncStorage.setItem(key, JSON.stringify(value)); 10 | } 11 | 12 | 13 | export function getItem(key) { 14 | return AsyncStorage.getItem(key) 15 | .then(function (value) { 16 | return JSON.parse(value) 17 | }); 18 | } 19 | 20 | 21 | export async function removeItem(...args) { 22 | return await AsyncStorage.removeItem(...args); 23 | } 24 | 25 | 26 | export function multiGet(keys) { 27 | return AsyncStorage.multiGet(keys) 28 | .then(results=> { 29 | return results.map(item=> { 30 | return [item[0], JSON.parse(item[1])] 31 | }) 32 | }); 33 | } 34 | 35 | 36 | export function multiRemove(keys) { 37 | return AsyncStorage.multiRemove(keys) 38 | } -------------------------------------------------------------------------------- /test/store/configureStore.js: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware } from 'redux'; 2 | import thunkMiddleware from 'redux-thunk'; 3 | 4 | const isDebuggingInChrome = __DEV__ && !!window.navigator.userAgent; 5 | 6 | const logger = createLogger({ 7 | predicate: (getState, action) => isDebuggingInChrome, 8 | collapsed: true, 9 | duration: true, 10 | }); 11 | 12 | let middlewares = [ 13 | thunkMiddleware 14 | ]; 15 | 16 | if (isDebuggingInChrome) { 17 | middlewares.push(logger); 18 | } 19 | 20 | export default function configureStore(initialState) { 21 | const store = applyMiddleware( 22 | ...middlewares 23 | )(createStore)(reducers, initialState); 24 | 25 | if (module.hot) { 26 | module.hot.accept(() => { 27 | const nextRootReducer = require('../reducers/index').default; 28 | store.replaceReducer(nextRootReducer); 29 | }); 30 | } 31 | 32 | if (isDebuggingInChrome) { 33 | window.store = store; 34 | } 35 | 36 | return store; 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import ReactNative, { 3 | Navigator, 4 | View, 5 | ListView, 6 | Text, 7 | Image 8 | } from 'react-native'; 9 | 10 | import WebView from './web'; 11 | 12 | export default class App extends Component { 13 | 14 | _renderScene = (route, navigator)=> { 15 | const Comp = route.component; 16 | if (Comp) { 17 | return 18 | } 19 | else { 20 | return ( 21 | 22 | 23 | ); 24 | } 25 | } 26 | render() { 27 | return ( 28 | { 32 | if (route.sceneConfig) { 33 | return route.sceneConfig; 34 | } 35 | return Navigator.SceneConfigs.PushFromRight; 36 | } 37 | } 38 | /> 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /js/actions/home.js: -------------------------------------------------------------------------------- 1 | import * as types from '../constants/ActionTypes'; 2 | import {kHomeUrl} from '../constants/HttpUrls'; 3 | 4 | // MARK: - Action Creator 5 | 6 | // 请求首页数据 7 | function requestHomeData() { 8 | return { 9 | type: types.Fetch_Home_Data, 10 | } 11 | } 12 | 13 | // 接收到首页数据 14 | function receiveHomeData(data) { 15 | console.log("receiveHomeData : ", data.activity) 16 | return { 17 | type: types.Fetch_Home_Data_Success, 18 | activity: data.activity, 19 | shop: data.shop, 20 | cases: data.cases, 21 | } 22 | } 23 | 24 | export function fetchHomeData() { 25 | console.log("fetchHomeData"); 26 | return (dispatch, getState) => { 27 | console.log("dispatch(requestHomeData())"); 28 | dispatch(requestHomeData()) 29 | return fetch(kHomeUrl,{}) 30 | .then(response => response.json()) 31 | .then(json => { 32 | return dispatch(receiveHomeData(json.data)) 33 | }) 34 | .catch(error => { 35 | console.log("Home Request Error"); 36 | }) 37 | .done() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ios/Marry/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "29x29", 5 | "idiom" : "iphone", 6 | "filename" : "AppIcon29x29@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "29x29", 11 | "idiom" : "iphone", 12 | "filename" : "AppIcon29x29@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "40x40", 17 | "idiom" : "iphone", 18 | "filename" : "AppIcon40x40@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "40x40", 23 | "idiom" : "iphone", 24 | "filename" : "AppIcon40x40@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "60x60", 29 | "idiom" : "iphone", 30 | "filename" : "AppIcon60x60@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "60x60", 35 | "idiom" : "iphone", 36 | "filename" : "AppIcon60x60@3x.png", 37 | "scale" : "3x" 38 | } 39 | ], 40 | "info" : { 41 | "version" : 1, 42 | "author" : "xcode" 43 | } 44 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## react-native-redux-marry 2 | ####运行效果 3 | ![(marry.gif)](https://github.com/zqmReactNative/react-native-redux-marry/blob/master/screenshot/marry_0614.gif) 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | ####运行iOS 13 | * 打开终端,切换到将用来保存项目的目录 14 | * checkout 15 | ```ruby 16 | git clone https://github.com/zqmReactNative/react-native-redux-marry.git 17 | ``` 18 | * 切换到项目根目录 19 | ```ruby 20 | cd react-native-redux-marry 21 | ``` 22 | * 加载依赖包(Node建议v6.0.0+) 23 | ```ruby 24 | npm install 25 | ``` 26 | * 找到`ios`目录,打开`Marry.xcodeproj` 27 | * 修改`AppDelegate.m`文件34行的IP地址(如果是真机调试,把localhost换成开启Node服务的设备IP,如果没有指定端口号,默认使用8081) 28 | ```ObjectiveC 29 | jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"]; 30 | ``` 31 | * 运行项目`command`+`R`或者Xcode左上角的运行按钮 32 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /index.android.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | */ 5 | 6 | import React, { 7 | AppRegistry, 8 | Component, 9 | StyleSheet, 10 | Text, 11 | View 12 | } from 'react-native'; 13 | 14 | class Marry extends Component { 15 | render() { 16 | return ( 17 | 18 | 19 | Welcome to React Native! 20 | 21 | 22 | To get started, edit index.android.js 23 | 24 | 25 | Shake or press menu button for dev menu 26 | 27 | 28 | ); 29 | } 30 | } 31 | 32 | const styles = StyleSheet.create({ 33 | container: { 34 | flex: 1, 35 | justifyContent: 'center', 36 | alignItems: 'center', 37 | backgroundColor: '#F5FCFF', 38 | }, 39 | welcome: { 40 | fontSize: 20, 41 | textAlign: 'center', 42 | margin: 10, 43 | }, 44 | instructions: { 45 | textAlign: 'center', 46 | color: '#333333', 47 | marginBottom: 5, 48 | }, 49 | }); 50 | 51 | AppRegistry.registerComponent('Marry', () => Marry); 52 | -------------------------------------------------------------------------------- /js/services/request.js: -------------------------------------------------------------------------------- 1 | // request.js 2 | 3 | import qs from 'query-string'; 4 | 5 | const urlPrefix = "http://"; 6 | 7 | 8 | function filterJSON(res) { 9 | return res.json(); 10 | } 11 | 12 | 13 | function filterStatus(res) { 14 | if (res.status >= 200 && res.status < 300) { 15 | return res 16 | } 17 | else { 18 | let error = new Error(res.statusText); 19 | error.res = res; 20 | error.type = 'http'; 21 | throw error; 22 | } 23 | } 24 | 25 | 26 | export function get(url, params) { 27 | url = urlPrefix + url; 28 | if (params) { 29 | url += `?${qs.stringify(params)}`; 30 | } 31 | 32 | if (__DEV__) { 33 | console.info(`GET: `, url); 34 | console.info(`Params: `, params) 35 | } 36 | 37 | return fetch(url) 38 | .then(filterStatus) 39 | .then(filterJSON); 40 | } 41 | 42 | 43 | export function post(url, body) { 44 | url = urlPrefix + url; 45 | 46 | if (__DEV__) { 47 | console.info(`POST: `, url); 48 | console.info(`Body: `, body) 49 | } 50 | 51 | return fetch(url, { 52 | method: 'POST', 53 | headers: { 54 | 'Accept': 'application/json', 55 | 'Content-Type': 'application/json' 56 | }, 57 | body: JSON.stringify(body) 58 | }) 59 | .then(filterStatus) 60 | .then(filterJSON); 61 | } -------------------------------------------------------------------------------- /android/app/src/main/java/com/marry/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.marry; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.facebook.react.ReactPackage; 5 | import com.facebook.react.shell.MainReactPackage; 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | public class MainActivity extends ReactActivity { 11 | 12 | /** 13 | * Returns the name of the main component registered from JavaScript. 14 | * This is used to schedule rendering of the component. 15 | */ 16 | @Override 17 | protected String getMainComponentName() { 18 | return "Marry"; 19 | } 20 | 21 | /** 22 | * Returns whether dev mode should be enabled. 23 | * This enables e.g. the dev menu. 24 | */ 25 | @Override 26 | protected boolean getUseDeveloperSupport() { 27 | return BuildConfig.DEBUG; 28 | } 29 | 30 | /** 31 | * A list of packages used by the app. If the app uses additional views 32 | * or modules besides the default ones, add more packages here. 33 | */ 34 | @Override 35 | protected List getPackages() { 36 | return Arrays.asList( 37 | new MainReactPackage() 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /js/common/SectionHeaderView.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from "react"; 2 | 3 | import { View, Text, Image, StyleSheet, Dimensions, TouchableOpacity, TouchableHighlight } from "react-native"; 4 | import Img from '../common/Img'; 5 | const screenWidth = Dimensions.get('window').width; 6 | const screenHeight = Dimensions.get('window').height; 7 | 8 | export default class SectionHeaderView extends Component { 9 | static propTypes = { 10 | ...View.propTypes, 11 | title:PropTypes.string, 12 | }; 13 | 14 | render(){ 15 | return ( 16 | 17 | 18 | 19 | 20 | {this.props.title} 21 | 22 | 23 | ); 24 | } 25 | } 26 | 27 | const styles = StyleSheet.create({ 28 | header:{ 29 | paddingHorizontal:10, 30 | height:30, 31 | alignItems:"center", 32 | flexDirection:"row" 33 | }, 34 | headerBorder:{ 35 | height:14, 36 | width:5, 37 | marginRight:8, 38 | borderRadius:1, 39 | backgroundColor:"#ff5942" 40 | }, 41 | headerText:{ 42 | color:"#151515", 43 | fontSize:15 44 | }, 45 | }); 46 | -------------------------------------------------------------------------------- /js/actions/album.js: -------------------------------------------------------------------------------- 1 | // album.js 2 | import * as types from "../constants/ActionTypes"; 3 | 4 | import { kAlbumUrl } from '../constants/HttpUrls'; 5 | 6 | 7 | function requestAlbumData() { 8 | return { 9 | type: types.Fetch_Album_Data, 10 | }; 11 | } 12 | 13 | function receiveAlbumData(data) { 14 | return { 15 | type: types.Fetch_Album_Data_Success, 16 | list: data.list, 17 | }; 18 | } 19 | 20 | function requestAlbumError(error) { 21 | return { 22 | type: types.Fetch_Album_Data_Failure, 23 | error: error, 24 | } 25 | } 26 | 27 | 28 | export function fetchAlbumData(page=1, areaid="", catid="123") { 29 | console.log("fetchAlbumData"); 30 | let url_request = { 31 | method: 'POST', 32 | body:JSON.stringify({ 33 | // "areaid": 0, 34 | // "catid": categories.defaultId, 35 | "page": 1 36 | }) 37 | } 38 | return (dispatch, getState) => { 39 | console.log("dispatch(requestAlbumData())"); 40 | dispatch(requestAlbumData()) 41 | return fetch(kAlbumUrl) 42 | .then(response => response.json()) 43 | .then(json => { 44 | console.log("receiveAlbumData"); 45 | return dispatch(receiveAlbumData(json.data)) 46 | }) 47 | .catch(error => { 48 | console.log("Album Request Error : ", error); 49 | return dispatch(requestAlbumError("图库数据请求失败.")) 50 | }) 51 | .done() 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ios/Marry/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSAppTransportSecurity 26 | 27 | NSAllowsArbitraryLoads 28 | 29 | 30 | NSLocationWhenInUseUsageDescription 31 | 32 | UIRequiredDeviceCapabilities 33 | 34 | armv7 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | 40 | UIViewControllerBasedStatusBarAppearance 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /js/actions/merchant.js: -------------------------------------------------------------------------------- 1 | // merchant.js 2 | 3 | import * as types from "../constants/ActionTypes"; 4 | 5 | import { kMerchantUrl } from '../constants/HttpUrls'; 6 | 7 | import * as categories from "../data/categories"; 8 | 9 | function requestMerchantData() { 10 | return { 11 | type: types.Fetch_Merchant_Data, 12 | }; 13 | } 14 | 15 | function receiveMerchantData(data) { 16 | return { 17 | type: types.Fetch_Merchant_Data_Success, 18 | list: data.shoplist, 19 | }; 20 | } 21 | 22 | function requestMerchantError(error) { 23 | return { 24 | type: types.Fetch_Merchant_Data_Failure, 25 | error: error, 26 | } 27 | } 28 | 29 | 30 | export function fetchMerchantData(page=1, areaid=0, catid=categories.defaultId) { 31 | console.log("fetchMerchantData"); 32 | let url_request = { 33 | method: 'POST', 34 | body:JSON.stringify({ 35 | "areaid": areaid, 36 | "catid": catid, 37 | "page": page 38 | }) 39 | } 40 | return (dispatch, getState) => { 41 | console.log("dispatch(fetchMerchantData())"); 42 | dispatch(requestMerchantData()) 43 | return fetch(kMerchantUrl, url_request) 44 | .then(response => response.json()) 45 | .then(json => { 46 | console.log("receiveMerchantData"); 47 | return dispatch(receiveMerchantData(json.data)) 48 | }) 49 | .catch(error => { 50 | console.log("Merchant Request Error : ", error); 51 | return dispatch(requestMerchantError("商家数据请求失败.")) 52 | }) 53 | .done() 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /js/data/categories.js: -------------------------------------------------------------------------------- 1 | export const defaultTitle = "婚纱摄影"; 2 | export const defaultId = 366; 3 | 4 | export const Categories = [ 5 | { 6 | id:268,title:"婚宴酒店", 7 | children:[ 8 | {id:328,title:"星级酒店"}, 9 | {id:363,title:"特色餐厅"}, 10 | {id:364,title:"婚礼会所"}, 11 | {id:398,title:"游轮婚礼"} 12 | ] 13 | }, 14 | { 15 | id:366,title:"婚纱摄影", 16 | children:[ 17 | {id:367,title:"摄影工作室"}, 18 | {id:368,title:"知名影楼"}, 19 | {id:399,title:"蜜月旅拍"} 20 | ] 21 | }, 22 | { 23 | id:359,title:"珠宝钻饰", 24 | children:[ 25 | {id:360,title:"楼中店"}, 26 | {id:361,title:"商场品牌"} 27 | ] 28 | }, 29 | { 30 | id:296,title:"婚礼策划", 31 | children:[ 32 | {id:305,title:"高端定制婚礼"}, 33 | {id:365,title:"个性定制婚礼"} 34 | ] 35 | }, 36 | { 37 | id:374,title:"新娘跟妆", 38 | children:[] 39 | }, 40 | { 41 | id:375,title:"主持跟拍", 42 | children:[ 43 | {id:376,title:"婚礼摄像"}, 44 | {id:377,title:"婚礼跟拍"}, 45 | {id:379,title:"主持司仪"} 46 | ] 47 | }, 48 | { 49 | id:380,title:"婚纱礼服", 50 | children:[ 51 | {id:384,title:"婚纱礼服"}, 52 | {id:381,title:"男士礼服"} 53 | ] 54 | }, 55 | { 56 | id:386,title:"婚礼百货", 57 | children:[ 58 | {id:410,title:"父母礼服"}, 59 | {id:387,title:"请柬/红包/礼金薄"}, 60 | {id:388,title:"喜糖"}, 61 | {id:402,title:"香烟/喜糖"}, 62 | {id:403,title:"甜品台"}, 63 | {id:405,title:"新娘美容"}, 64 | {id:406,title:"花艺/花车"}, 65 | {id:407,title:"家纺床品"} 66 | ] 67 | } 68 | ]; 69 | -------------------------------------------------------------------------------- /js/constants/ActionTypes.js: -------------------------------------------------------------------------------- 1 | // ActionTypes.js 2 | // 定义Redux type常量 3 | 4 | // Home 首页 5 | export const Fetch_Home_Data = "Fetch_Home_Data"; 6 | export const Fetch_Home_Data_Success = "Fetch_Home_Data_Success"; 7 | export const Fetch_Home_Data_Failure = "Fetch_Home_Data_Failure"; 8 | 9 | export const Fetch_Home_Data_More = "Fetch_Home_Data_More"; 10 | export const Fetch_Home_Data_More_Success = "Fetch_Home_Data_More_Success"; 11 | export const Fetch_Home_Data_More_Failure = "Fetch_Home_Data_More_Failure"; 12 | 13 | // Album 图库 14 | export const Fetch_Album_Data = "Fetch_Album_Data"; 15 | export const Fetch_Album_Data_Success = "Fetch_Album_Data_Success"; 16 | export const Fetch_Album_Data_Failure = "Fetch_Album_Data_Failure"; 17 | 18 | export const Fetch_Album_Data_More = "Fetch_Album_Data_More"; 19 | export const Fetch_Album_Data_More_Success = "Fetch_Album_Data_More_Success"; 20 | export const Fetch_Album_Data_More_Failure = "Fetch_Album_Data_More_Failure"; 21 | 22 | // Merchant 商店 23 | export const Fetch_Merchant_Data = "Fetch_Merchant_Data"; 24 | export const Fetch_Merchant_Data_Success = "Fetch_Merchant_Data_Success"; 25 | export const Fetch_Merchant_Data_Failure = "Fetch_Merchant_Data_Failure"; 26 | 27 | export const Fetch_Merchant_Data_More = "Fetch_Merchant_Data_More"; 28 | export const Fetch_Merchant_Data_More_Success = "Fetch_Merchant_Data_More_Success"; 29 | export const Fetch_Merchant_Data_More_Failure = "Fetch_Merchant_Data_More_Failure"; 30 | 31 | export const REQUEST_HOME_DATA = "REQUEST_HOME_DATA"; 32 | export const REQUEST_ALBUM_LIST = "REQUEST_ALBUM_LIST"; 33 | -------------------------------------------------------------------------------- /android/app/BUCK: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | # To learn about Buck see [Docs](https://buckbuild.com/). 4 | # To run your application with Buck: 5 | # - install Buck 6 | # - `npm start` - to start the packager 7 | # - `cd android` 8 | # - `cp ~/.android/debug.keystore keystores/debug.keystore` 9 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 10 | # - `buck install -r android/app` - compile, install and run application 11 | # 12 | 13 | lib_deps = [] 14 | for jarfile in glob(['libs/*.jar']): 15 | name = 'jars__' + re.sub(r'^.*/([^/]+)\.jar$', r'\1', jarfile) 16 | lib_deps.append(':' + name) 17 | prebuilt_jar( 18 | name = name, 19 | binary_jar = jarfile, 20 | ) 21 | 22 | for aarfile in glob(['libs/*.aar']): 23 | name = 'aars__' + re.sub(r'^.*/([^/]+)\.aar$', r'\1', aarfile) 24 | lib_deps.append(':' + name) 25 | android_prebuilt_aar( 26 | name = name, 27 | aar = aarfile, 28 | ) 29 | 30 | android_library( 31 | name = 'all-libs', 32 | exported_deps = lib_deps 33 | ) 34 | 35 | android_library( 36 | name = 'app-code', 37 | srcs = glob([ 38 | 'src/main/java/**/*.java', 39 | ]), 40 | deps = [ 41 | ':all-libs', 42 | ':build_config', 43 | ':res', 44 | ], 45 | ) 46 | 47 | android_build_config( 48 | name = 'build_config', 49 | package = 'com.marry', 50 | ) 51 | 52 | android_resource( 53 | name = 'res', 54 | res = 'src/main/res', 55 | package = 'com.marry', 56 | ) 57 | 58 | android_binary( 59 | name = 'app', 60 | package_type = 'debug', 61 | manifest = 'src/main/AndroidManifest.xml', 62 | keystore = '//android/keystores:debug', 63 | deps = [ 64 | ':app-code', 65 | ], 66 | ) 67 | -------------------------------------------------------------------------------- /webdetail.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import ReactNative, { 3 | Navigator, 4 | View, 5 | StyleSheet, 6 | ListView, 7 | Text, 8 | Image, 9 | TouchableOpacity, 10 | Dimensions, 11 | WebView 12 | } from 'react-native'; 13 | 14 | const kScreenWidth = Dimensions.get('window').width; 15 | const kScreenHeight = Dimensions.get('window').height; 16 | 17 | export default class WebDetail extends Component { 18 | render() { 19 | const {url} = this.props; 20 | console.log(url); 21 | return ( 22 | 23 | 24 | 25 | 26 | 27 | { 29 | this.props.navigator && this.props.navigator.pop() 30 | }} 31 | style={{fontSize: 12, color: 'white'}} 32 | > 33 | 返回 34 | 35 | 36 | 37 | 38 | 42 | 43 | 44 | ); 45 | 46 | } 47 | } 48 | 49 | const styles = StyleSheet.create({ 50 | container: { 51 | flex: 1, 52 | backgroundColor: 'white', 53 | }, 54 | bar: { 55 | height: 64, 56 | alignItems: 'center', 57 | // justifyContent: 'space-between', 58 | backgroundColor: 'rgb(14, 140, 226)', 59 | }, 60 | webview: { 61 | flex: 1, 62 | }, 63 | }); 64 | -------------------------------------------------------------------------------- /ios/Marry/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "extent" : "full-screen", 5 | "idiom" : "iphone", 6 | "subtype" : "736h", 7 | "filename" : "LaunchImage-800-Portrait-736h@3x.png", 8 | "minimum-system-version" : "8.0", 9 | "orientation" : "portrait", 10 | "scale" : "3x" 11 | }, 12 | { 13 | "extent" : "full-screen", 14 | "idiom" : "iphone", 15 | "subtype" : "667h", 16 | "filename" : "LaunchImage-800-667h@2x.png", 17 | "minimum-system-version" : "8.0", 18 | "orientation" : "portrait", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "orientation" : "portrait", 23 | "idiom" : "iphone", 24 | "filename" : "LaunchImage-700@2x.png", 25 | "extent" : "full-screen", 26 | "minimum-system-version" : "7.0", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "extent" : "full-screen", 31 | "idiom" : "iphone", 32 | "subtype" : "retina4", 33 | "filename" : "LaunchImage-700-568h@2x.png", 34 | "minimum-system-version" : "7.0", 35 | "orientation" : "portrait", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "orientation" : "portrait", 40 | "idiom" : "iphone", 41 | "filename" : "LaunchImage.png", 42 | "extent" : "full-screen", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "orientation" : "portrait", 47 | "idiom" : "iphone", 48 | "filename" : "LaunchImage@2x.png", 49 | "extent" : "full-screen", 50 | "scale" : "2x" 51 | }, 52 | { 53 | "orientation" : "portrait", 54 | "idiom" : "iphone", 55 | "extent" : "full-screen", 56 | "subtype" : "retina4", 57 | "scale" : "2x" 58 | } 59 | ], 60 | "info" : { 61 | "version" : 1, 62 | "author" : "xcode" 63 | } 64 | } -------------------------------------------------------------------------------- /js/components/DetailHeader.js: -------------------------------------------------------------------------------- 1 | // DetailHeader.js 2 | // 详情页头部视图 3 | 4 | import React, { Component, PropTypes } from "react"; 5 | 6 | import { View, Text, Image, StyleSheet, Dimensions } from "react-native"; 7 | import Stars from '../svg/Stars'; 8 | import Img from '../common/Img'; 9 | 10 | const screenWidth = Dimensions.get('window').width; 11 | const screenHeight = Dimensions.get('window').height; 12 | 13 | export default class DetailHeader extends Component { 14 | static propTypes = { 15 | ...View.propTypes, 16 | source: Image.propTypes.source, 17 | title: PropTypes.string, 18 | detailTitle: PropTypes.string, 19 | level:PropTypes.oneOfType([PropTypes.string, PropTypes.number]), 20 | } 21 | static defaultProps = { 22 | level:0, 23 | title:"", 24 | detailTitle:"", 25 | } 26 | 27 | render() { 28 | const { source, title, detailTitle, level } = this.props; 29 | return ( 30 | 31 | 32 | 33 | {title} 34 | 35 | {detailTitle} 36 | 37 | 38 | ); 39 | } 40 | } 41 | 42 | const styles = StyleSheet.create({ 43 | container: { 44 | height:112, 45 | backgroundColor: 'white', 46 | flexDirection: 'row', 47 | // alignItems: 'center', 48 | padding: 16, 49 | }, 50 | image: { 51 | width: 80, 52 | height: 80, 53 | // backgroundColor: '#565656', 54 | borderRadius: 5, 55 | // marginLeft: 15, 56 | }, 57 | rightContainer: { 58 | marginLeft: 13, 59 | marginRight: 16, 60 | }, 61 | title: { 62 | fontSize: 20, 63 | marginBottom: 10, 64 | }, 65 | detailTitle: { 66 | fontSize: 15, 67 | color: '#3b3b3b', 68 | marginTop: 10, 69 | width: screenWidth - 16 - 80 - 13 - 16, 70 | } 71 | }); 72 | -------------------------------------------------------------------------------- /js/reducers/album.js: -------------------------------------------------------------------------------- 1 | // album.js 2 | // Album Reducer 3 | 4 | import * as types from "../constants/ActionTypes"; 5 | const initialState = { 6 | isChangedOption: true, // 筛选条件 7 | isRefreshing: true, 8 | isLoading: true, 9 | isLoadMore: false, 10 | isError: false, 11 | list: [], 12 | }; 13 | 14 | export default function album(state = initialState, action) { 15 | console.log("album reducer"); 16 | switch (action.type) 17 | { 18 | case types.Fetch_Album_Data: 19 | return { 20 | ...state, 21 | isRefreshing: true, 22 | isLoading: true, 23 | isLoadMore: false, 24 | isError: false, 25 | } 26 | break; 27 | case types.Fetch_Album_Data_Success: 28 | return { 29 | ...state, 30 | isChangedOption: false, 31 | isRefreshing: false, 32 | isLoading: false, 33 | isLoadMore: false, 34 | isError: false, 35 | list: action.list, 36 | } 37 | break; 38 | case types.Fetch_Album_Data_Failure: 39 | return { 40 | ...state, 41 | isChangedOption: true, 42 | isRefreshing: false, 43 | isLoading: false, 44 | isLoadMore: false, 45 | isError: true, 46 | error: action.error, 47 | } 48 | break; 49 | case types.Fetch_Album_Data_More: 50 | return { 51 | ...state, 52 | isChangedOption: false, 53 | isRefreshing: false, 54 | isLoading: true, 55 | isLoadMore: true, 56 | isError: false, 57 | } 58 | break; 59 | case types.Fetch_Album_Data_More_Success: 60 | return { 61 | ...state, 62 | isChangedOption: false, 63 | isRefreshing: false, 64 | isLoading: false, 65 | isLoadMore: false, 66 | isError: false, 67 | list: state.list.concat(action.list), 68 | } 69 | break; 70 | case types.Fetch_Album_Data_More_Failure: 71 | return { 72 | ...state, 73 | isChangedOption: true, 74 | isRefreshing: false, 75 | isLoading: false, 76 | isLoadMore: false, 77 | isError: true, 78 | error: action.error, 79 | } 80 | break; 81 | default: 82 | return state; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /js/reducers/merchant.js: -------------------------------------------------------------------------------- 1 | // merchant.js 2 | // Merchant Reducer 3 | 4 | import * as types from "../constants/ActionTypes"; 5 | const initialState = { 6 | isChangedOption: true, // 筛选条件 7 | isRefreshing: true, 8 | isLoading: true, 9 | isLoadMore: false, 10 | isError: false, 11 | list: [], 12 | }; 13 | 14 | export default function merchant(state = initialState, action) { 15 | console.log("merchant reducer"); 16 | switch (action.type) 17 | { 18 | case types.Fetch_Merchant_Data: 19 | return { 20 | ...state, 21 | isRefreshing: true, 22 | isLoading: true, 23 | isLoadMore: false, 24 | isError: false, 25 | } 26 | break; 27 | case types.Fetch_Merchant_Data_Success: 28 | return { 29 | ...state, 30 | isChangedOption: false, 31 | isRefreshing: false, 32 | isLoading: false, 33 | isLoadMore: false, 34 | isError: false, 35 | list: action.list, 36 | } 37 | break; 38 | case types.Fetch_Merchant_Data_Failure: 39 | return { 40 | ...state, 41 | isChangedOption: true, 42 | isRefreshing: false, 43 | isLoading: false, 44 | isLoadMore: false, 45 | isError: true, 46 | error: action.error, 47 | } 48 | break; 49 | case types.Fetch_Merchant_Data_More: 50 | return { 51 | ...state, 52 | isChangedOption: false, 53 | isRefreshing: false, 54 | isLoading: true, 55 | isLoadMore: true, 56 | isError: false, 57 | } 58 | break; 59 | case types.Fetch_Merchant_Data_More_Success: 60 | return { 61 | ...state, 62 | isChangedOption: false, 63 | isRefreshing: false, 64 | isLoading: false, 65 | isLoadMore: false, 66 | isError: false, 67 | list: state.list.concat(action.list), 68 | } 69 | break; 70 | case types.Fetch_Merchant_Data_More_Failure: 71 | return { 72 | ...state, 73 | isChangedOption: true, 74 | isRefreshing: false, 75 | isLoading: false, 76 | isLoadMore: false, 77 | isError: true, 78 | error: action.error, 79 | } 80 | break; 81 | default: 82 | return state; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /js/reducers/home.js: -------------------------------------------------------------------------------- 1 | import * as types from '../constants/ActionTypes'; 2 | 3 | const initialState = { 4 | isRefreshing: true, 5 | isLoading: true, 6 | isLoadMore: false, 7 | isError: false, 8 | activity: [{}, {}], 9 | shop: [{}, {}, {}, {}], 10 | cases: [{}, {}, {}, {}], 11 | }; 12 | 13 | export default function home(state=initialState, action){ 14 | console.log("homeReducer type : ", action.type); 15 | switch (action.type) { 16 | case types.Fetch_Home_Data: 17 | return { 18 | ...state, 19 | isRefreshing: true, 20 | isLoading: true, 21 | isLoadMore: false, 22 | isError: false, 23 | }; 24 | case types.Fetch_Home_Data_Success: 25 | return { 26 | ...state, 27 | isRefreshing: false, 28 | isLoading: false, 29 | isLoadMore: false, 30 | isError: false, 31 | activity: action.activity, 32 | shop: action.shop, 33 | cases: action.cases, 34 | }; 35 | case types.Fetch_Home_Data_Failure: 36 | return { 37 | ...state, 38 | isRefreshing: false, 39 | isLoading: false, 40 | isLoadMore: false, 41 | isError: true, 42 | }; 43 | case types.Fetch_Home_Data_More: 44 | return { 45 | ...state, 46 | isRefreshing: false, 47 | isLoading: true, 48 | isLoadMore: true, 49 | isError: false, 50 | }; 51 | case types.Fetch_Home_Data_More_Success: 52 | return { 53 | ...state, 54 | isRefreshing: false, 55 | isLoading: false, 56 | isLoadMore: false, 57 | isError: false, 58 | activity: state.activity.concat(action.activity), 59 | shop: state.shop.concat(action.shop), 60 | cases: state.cases.concat(action.cases), 61 | }; 62 | case types.Fetch_Home_Data_More_Failure: 63 | return { 64 | ...state, 65 | isRefreshing: false, 66 | isLoading: false, 67 | isLoadMore: false, 68 | isError: true, 69 | error: action.error, 70 | }; 71 | break; 72 | default: 73 | return state; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /js/Cell/MerchantDetailCell.js: -------------------------------------------------------------------------------- 1 | // MerchantDetailCell.js 2 | // 用于商品页的cell 3 | 4 | import React, { Component, PropTypes } from "react"; 5 | 6 | import { View, Text, Image, StyleSheet, Dimensions, TouchableOpacity, TouchableHighlight } from "react-native"; 7 | import Img from '../common/Img'; 8 | const screenWidth = Dimensions.get('window').width; 9 | const screenHeight = Dimensions.get('window').height; 10 | 11 | const cellPadding = 10; 12 | const cellHeight_I5 = 380; 13 | const textHeight = 35; 14 | const cellHeight = cellHeight_I5*screenWidth/640; 15 | const imageHeight = cellHeight - textHeight - cellPadding; 16 | const imageWidth = screenWidth - 2*cellPadding; 17 | export default class MerchantDetailCell extends Component { 18 | static propTypes = { 19 | ...View.propTypes, 20 | source: Image.propTypes.source, 21 | imageStyle: Image.propTypes.style, 22 | textContainer: View.propTypes.style, 23 | textStyle: Text.propTypes.style, 24 | title: PropTypes.string, 25 | onPress:PropTypes.func, 26 | } 27 | render() { 28 | const { style, imageStyle, textContainer, textStyle, title, source } = this.props; 29 | 30 | return ( 31 | 36 | 37 | 38 | 39 | {title} 40 | 41 | 42 | 43 | ); 44 | } 45 | } 46 | 47 | const styles = StyleSheet.create({ 48 | container: { 49 | flex: 1, 50 | height: cellHeight, 51 | // alignItems: 'center', 52 | // justifyContent: 'center', 53 | padding: 10, 54 | // marginBottom: 10 55 | backgroundColor: 'white', 56 | }, 57 | image: { 58 | width: imageWidth, 59 | height: imageHeight, 60 | // backgroundColor: 'rgb(247, 247, 247)', 61 | }, 62 | textContainer: { 63 | // position: 'absolute', 64 | // left: 0, 65 | // right: 0, 66 | // bottom: 0, 67 | height: textHeight, 68 | // paddingLeft: cellPadding, 69 | // paddingRight: cellPadding, 70 | // alignItems: 'center', 71 | justifyContent: 'center', 72 | backgroundColor: 'white', 73 | }, 74 | text: { 75 | color: '#333', 76 | }, 77 | }); 78 | -------------------------------------------------------------------------------- /ios/Marry/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AppDelegate.h" 11 | 12 | #import "RCTRootView.h" 13 | 14 | @implementation AppDelegate 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | NSURL *jsCodeLocation; 19 | 20 | /** 21 | * Loading JavaScript code - uncomment the one you want. 22 | * 23 | * OPTION 1 24 | * Load from development server. Start the server from the repository root: 25 | * 26 | * $ npm start 27 | * 28 | * To run on device, change `localhost` to the IP address of your computer 29 | * (you can get this by typing `ifconfig` into the terminal and selecting the 30 | * `inet` value under `en0:`) and make sure your computer and iOS device are 31 | * on the same Wi-Fi network. 32 | */ 33 | 34 | jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"]; 35 | 36 | /** 37 | * OPTION 2 38 | * Load from pre-bundled file on disk. The static bundle is automatically 39 | * generated by the "Bundle React Native code and images" build step when 40 | * running the project on an actual device or running the project on the 41 | * simulator in the "Release" build configuration. 42 | */ 43 | 44 | // jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 45 | 46 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 47 | moduleName:@"Marry" 48 | initialProperties:nil 49 | launchOptions:launchOptions]; 50 | 51 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 52 | UIViewController *rootViewController = [UIViewController new]; 53 | rootViewController.view = rootView; 54 | self.window.rootViewController = rootViewController; 55 | [self.window makeKeyAndVisible]; 56 | return YES; 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /ios/MarryTests/MarryTests.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | #import 12 | 13 | #import "RCTLog.h" 14 | #import "RCTRootView.h" 15 | 16 | #define TIMEOUT_SECONDS 240 17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" 18 | 19 | @interface MarryTests : XCTestCase 20 | 21 | @end 22 | 23 | @implementation MarryTests 24 | 25 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 26 | { 27 | if (test(view)) { 28 | return YES; 29 | } 30 | for (UIView *subview in [view subviews]) { 31 | if ([self findSubviewInView:subview matching:test]) { 32 | return YES; 33 | } 34 | } 35 | return NO; 36 | } 37 | 38 | - (void)testRendersWelcomeScreen 39 | { 40 | UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; 41 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 42 | BOOL foundElement = NO; 43 | 44 | __block NSString *redboxError = nil; 45 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 46 | if (level >= RCTLogLevelError) { 47 | redboxError = message; 48 | } 49 | }); 50 | 51 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 52 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 53 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 54 | 55 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 56 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 57 | return YES; 58 | } 59 | return NO; 60 | }]; 61 | } 62 | 63 | RCTSetLogFunction(RCTDefaultLogFunction); 64 | 65 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 66 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 67 | } 68 | 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /js/views/FilterHeaderView.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from "react"; 2 | import { ScrollView, View, Text, Image, StyleSheet, RefreshControl, TouchableOpacity, TouchableHighlight, PixelRatio } from "react-native"; 3 | 4 | 5 | 6 | export default class FilterHeaderView extends Component { 7 | static propTypes = { 8 | leftButtonTitle: PropTypes.string, 9 | rightButtonTitle: PropTypes.string, 10 | onPressLeft: PropTypes.func, 11 | onPressRight: PropTypes.func, 12 | } 13 | static defaultProps = { 14 | leftButtonTitle: "", 15 | rightButtonTitle: "", 16 | } 17 | _onPressLeft = ()=>{ 18 | if (this.props.onPressLeft) { 19 | this.props.onPressLeft(); 20 | } 21 | } 22 | _onPressRight = ()=>{ 23 | if (this.props.onPressRight) { 24 | this.props.onPressRight(); 25 | } 26 | } 27 | render() { 28 | return ( 29 | 30 | 36 | 37 | {this.props.leftButtonTitle} 38 | 39 | 40 | 41 | 42 | 48 | 49 | {this.props.rightButtonTitle} 50 | 51 | 52 | 53 | ); 54 | } 55 | } 56 | 57 | const styles = StyleSheet.create({ 58 | container: { 59 | height: 40, 60 | flexDirection: 'row', 61 | alignItems: 'center', 62 | justifyContent: 'center', 63 | backgroundColor: 'white', 64 | borderBottomColor: '#ccc', 65 | borderBottomWidth: 1/PixelRatio.get(), 66 | }, 67 | button: { 68 | flex: 1, 69 | flexDirection: 'row', 70 | alignItems: 'center', 71 | justifyContent: 'center', 72 | // backgroundColor: 'pink', 73 | marginTop: 0, 74 | marginBottom: 0, 75 | height: 40, 76 | }, 77 | dividerLine: { 78 | // marginTop: 5, 79 | // marginBottom: 5, 80 | height: 31, 81 | width: 1/PixelRatio.get(), 82 | backgroundColor: '#ccc', 83 | }, 84 | text: { 85 | fontSize: 12, 86 | // color: 'red', 87 | }, 88 | }); 89 | -------------------------------------------------------------------------------- /js/common/CommonCell.js: -------------------------------------------------------------------------------- 1 | // CommonCell.js 2 | 3 | import React, { 4 | Component, 5 | PropTypes, 6 | } from 'react'; 7 | 8 | import ReactNative, { 9 | StyleSheet, 10 | View, 11 | Text, 12 | TouchableHighlight, 13 | TouchableOpacity, 14 | TouchableWithoutFeedback, 15 | } from 'react-native'; 16 | 17 | export default class CommonCell extends Component{ 18 | static propTypes = { 19 | ...View.propTypes.style, 20 | ...TouchableHighlight.propTypes.style, 21 | // ...TouchableOpacity.propTypes.style, 22 | // ...TouchableWithoutFeedback.propTypes.style, 23 | renderCellContent: PropTypes.func.isRequired, 24 | onPressIn: PropTypes.func, 25 | onPressOut: PropTypes.func, 26 | onPress: PropTypes.func, 27 | disabled: PropTypes.bool, 28 | contentContainerStyle: View.propTypes.style 29 | }; 30 | static defaultProps = { 31 | onPress: ()=>{}, 32 | renderCellContent: ()=>, 33 | }; 34 | 35 | _getContent = ()=>{ 36 | // TouchableHighlight拥有underlayColor属性 37 | if(this.props.underlayColor){ 38 | 39 | return ( 40 | 46 | { this.props.renderCellContent() } 47 | 48 | ); 49 | } 50 | else { 51 | // TouchableHighlight,TouchableOpacity都有activeOpacity属性 52 | if (this.props.activeOpacity) { 53 | return ( 54 | 59 | { this.props.renderCellContent() } 60 | 61 | ); 62 | } 63 | else { 64 | return ( 65 | 69 | { this.props.renderCellContent() } 70 | 71 | ); 72 | } 73 | } 74 | 75 | }; 76 | 77 | _pressHandler = ()=>{ 78 | if (this.props.onPress) { 79 | this.props.onPress(); 80 | } 81 | }; 82 | 83 | render() { 84 | return ( 85 | this._getContent() 86 | ); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Disabling obfuscation is useful if you collect stack traces from production crashes 20 | # (unless you are using a system that supports de-obfuscate the stack traces). 21 | -dontobfuscate 22 | 23 | # React Native 24 | 25 | # Keep our interfaces so they can be used by other ProGuard rules. 26 | # See http://sourceforge.net/p/proguard/bugs/466/ 27 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip 28 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters 29 | 30 | # Do not strip any method/class that is annotated with @DoNotStrip 31 | -keep @com.facebook.proguard.annotations.DoNotStrip class * 32 | -keepclassmembers class * { 33 | @com.facebook.proguard.annotations.DoNotStrip *; 34 | } 35 | 36 | -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * { 37 | void set*(***); 38 | *** get*(); 39 | } 40 | 41 | -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; } 42 | -keep class * extends com.facebook.react.bridge.NativeModule { *; } 43 | -keepclassmembers,includedescriptorclasses class * { native ; } 44 | -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; } 45 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; } 46 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; } 47 | 48 | -dontwarn com.facebook.react.** 49 | 50 | # okhttp 51 | 52 | -keepattributes Signature 53 | -keepattributes *Annotation* 54 | -keep class com.squareup.okhttp.** { *; } 55 | -keep interface com.squareup.okhttp.** { *; } 56 | -dontwarn com.squareup.okhttp.** 57 | 58 | # okio 59 | 60 | -keep class sun.misc.Unsafe { *; } 61 | -dontwarn java.nio.file.* 62 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 63 | -dontwarn okio.** 64 | 65 | # stetho 66 | 67 | -dontwarn com.facebook.stetho.** 68 | -------------------------------------------------------------------------------- /js/detail/ActivityDetailView.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from "react"; 2 | 3 | import { View, Text, Image, StyleSheet, Dimensions, ListView, RefreshControl, TouchableOpacity, TouchableHighlight } from "react-native"; 4 | import Img from '../common/Img'; 5 | const screenWidth = Dimensions.get('window').width; 6 | const screenHeight = Dimensions.get('window').height; 7 | 8 | import NavigatorHeader from '../common/NavigatorHeader'; 9 | 10 | export default class ActivityDetailView extends Component { 11 | constructor(props) { 12 | super(props); 13 | let ds = new ListView.DataSource({ 14 | rowHasChanged: (r1, r2) => r1 !== r2, 15 | }); 16 | this.state = { 17 | dataSource: ds.cloneWithRows([]), 18 | }; 19 | } 20 | _renderHeader = () => { 21 | return ( 22 | 23 | 24 | 25 | 26 | 订婚宴,返200现金! 27 | 28 | 29 | 30 | 31 | 活动时间:2016.01.13-2016.12.31 32 | 33 | 34 | 35 | 36 | 进店看看 37 | 38 | 39 | 40 | 41 | ); 42 | } 43 | _onRefresh = () => { 44 | // TODO: 45 | } 46 | render() { 47 | return ( 48 | 49 | 50 | ({"<"})} title={"活动详情"}/> 51 | } 54 | enableEmptySections = {true} 55 | renderHeader={this._renderHeader} 56 | refreshControl={ 57 | 62 | } 63 | /> 64 | 65 | 66 | ); 67 | } 68 | } 69 | const kScale = screenWidth / 375; 70 | const kImageH = kScale * 230; 71 | const kImageW = screenWidth; 72 | const styles = StyleSheet.create({ 73 | container: { 74 | flex: 1, 75 | backgroundColor: 'white', 76 | }, 77 | header: { 78 | // height: 410, 79 | // width: screenWidth, 80 | // flex: 1, 81 | backgroundColor: 'red', 82 | }, 83 | image: { 84 | height: kImageH, 85 | width: kImageW, 86 | }, 87 | 88 | }) 89 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /js/svg/Stars.js: -------------------------------------------------------------------------------- 1 | // Stars.js 2 | 3 | import React,{ 4 | Component, 5 | PropTypes, 6 | } from 'react'; 7 | 8 | import { 9 | StyleSheet, 10 | View, 11 | } from 'react-native'; 12 | 13 | import Svg, { 14 | Circle, 15 | G, 16 | Path, 17 | Polygon, 18 | } from 'react-native-svg'; 19 | 20 | class Star extends Component { 21 | 22 | static propTypes = { 23 | ...View.propTypes, 24 | active:PropTypes.bool, 25 | }; 26 | 27 | static defaultProps = { 28 | active:false, 29 | }; 30 | 31 | render(){ 32 | return ( 33 | 34 | 38 | 41 | 45 | 46 | 47 | 48 | 49 | 50 | ); 51 | } 52 | 53 | 54 | } 55 | 56 | export default class Stars extends Component { 57 | 58 | static propTypes = { 59 | ...View.propTypes, 60 | count:PropTypes.number, 61 | }; 62 | 63 | static defaultProps = { 64 | count:0, 65 | } 66 | 67 | 68 | 69 | _getStars = (activeCount=0, starsCount=5)=>{ 70 | 71 | var stars=[]; 72 | for (var i = 0; i < activeCount; i++) { 73 | stars.push({active:true}) 74 | } 75 | for (var i = activeCount; i < starsCount; i++) { 76 | stars.push({active:false}) 77 | } 78 | return ( 79 | 80 | { 81 | stars.map( 82 | (item, index)=>{ 83 | return ( 84 | 85 | ); 86 | } 87 | ) 88 | } 89 | 90 | ); 91 | } 92 | 93 | render(){ 94 | return ( 95 | this._getStars(this.props.count) 96 | ); 97 | } 98 | 99 | 100 | 101 | } 102 | 103 | const styles = StyleSheet.create({ 104 | container:{ 105 | flexDirection:"row" 106 | }, 107 | box:{ 108 | width:13.5, 109 | height:13.5 110 | } 111 | }); 112 | -------------------------------------------------------------------------------- /js/common/Img.js: -------------------------------------------------------------------------------- 1 | // 用于占位图 2 | 3 | import React, { 4 | Component, 5 | PropTypes, 6 | } from 'react'; 7 | 8 | import ReactNative, { 9 | StyleSheet, 10 | View, 11 | Image, 12 | } from 'react-native'; 13 | 14 | var ReactNativeART = ReactNative.ART; 15 | var { 16 | Group, 17 | Shape, 18 | // Circle, 19 | Surface, 20 | // Transform, 21 | // Rectangle, 22 | } = ReactNativeART; 23 | 24 | export default class Img extends Component{ 25 | 26 | static propTypes = { 27 | ...View.propTypes, 28 | source:Image.propTypes.source 29 | }; 30 | 31 | render(){ 32 | const { imageStyle, source } = this.props; 33 | return ( 34 | 35 | 39 | 43 | 47 | 50 | 53 | 54 | 55 | 56 | 57 | ); 58 | 59 | } 60 | } 61 | 62 | const styles = StyleSheet.create({ 63 | container:{ 64 | width: 40, 65 | height: 40, 66 | alignItems: 'center', 67 | justifyContent: 'center', 68 | backgroundColor:"#ededed", 69 | }, 70 | cover:{ 71 | position:"absolute", 72 | top:0, 73 | right:0, 74 | bottom:0, 75 | left:0, 76 | // alignItems:"center", 77 | // justifyContent:"center", 78 | // backgroundColor:"#ededed", 79 | // backgroundColor:"red" 80 | }, 81 | icon:{ 82 | height:40, 83 | width:40 84 | } 85 | }); 86 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | 3 | # We fork some components by platform. 4 | .*/*.web.js 5 | .*/*.android.js 6 | 7 | # Some modules have their own node_modules with overlap 8 | .*/node_modules/node-haste/.* 9 | 10 | # Ugh 11 | .*/node_modules/babel.* 12 | .*/node_modules/babylon.* 13 | .*/node_modules/invariant.* 14 | 15 | # Ignore react and fbjs where there are overlaps, but don't ignore 16 | # anything that react-native relies on 17 | .*/node_modules/fbjs/lib/Map.js 18 | .*/node_modules/fbjs/lib/fetch.js 19 | .*/node_modules/fbjs/lib/ExecutionEnvironment.js 20 | .*/node_modules/fbjs/lib/ErrorUtils.js 21 | 22 | # Flow has a built-in definition for the 'react' module which we prefer to use 23 | # over the currently-untyped source 24 | .*/node_modules/react/react.js 25 | .*/node_modules/react/lib/React.js 26 | .*/node_modules/react/lib/ReactDOM.js 27 | 28 | .*/__mocks__/.* 29 | .*/__tests__/.* 30 | 31 | .*/commoner/test/source/widget/share.js 32 | 33 | # Ignore commoner tests 34 | .*/node_modules/commoner/test/.* 35 | 36 | # See https://github.com/facebook/flow/issues/442 37 | .*/react-tools/node_modules/commoner/lib/reader.js 38 | 39 | # Ignore jest 40 | .*/node_modules/jest-cli/.* 41 | 42 | # Ignore Website 43 | .*/website/.* 44 | 45 | # Ignore generators 46 | .*/local-cli/generator.* 47 | 48 | # Ignore BUCK generated folders 49 | .*\.buckd/ 50 | 51 | .*/node_modules/is-my-json-valid/test/.*\.json 52 | .*/node_modules/iconv-lite/encodings/tables/.*\.json 53 | .*/node_modules/y18n/test/.*\.json 54 | .*/node_modules/spdx-license-ids/spdx-license-ids.json 55 | .*/node_modules/spdx-exceptions/index.json 56 | .*/node_modules/resolve/test/subdirs/node_modules/a/b/c/x.json 57 | .*/node_modules/resolve/lib/core.json 58 | .*/node_modules/jsonparse/samplejson/.*\.json 59 | .*/node_modules/json5/test/.*\.json 60 | .*/node_modules/ua-parser-js/test/.*\.json 61 | .*/node_modules/builtin-modules/builtin-modules.json 62 | .*/node_modules/binary-extensions/binary-extensions.json 63 | .*/node_modules/url-regex/tlds.json 64 | .*/node_modules/joi/.*\.json 65 | .*/node_modules/isemail/.*\.json 66 | .*/node_modules/tr46/.*\.json 67 | 68 | 69 | [include] 70 | 71 | [libs] 72 | node_modules/react-native/Libraries/react-native/react-native-interface.js 73 | node_modules/react-native/flow 74 | flow/ 75 | 76 | [options] 77 | module.system=haste 78 | 79 | esproposal.class_static_fields=enable 80 | esproposal.class_instance_fields=enable 81 | 82 | munge_underscores=true 83 | 84 | module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub' 85 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\)$' -> 'RelativeImageStub' 86 | 87 | suppress_type=$FlowIssue 88 | suppress_type=$FlowFixMe 89 | suppress_type=$FixMe 90 | 91 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-2]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 92 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-2]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 93 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 94 | 95 | [version] 96 | ^0.22.0 97 | -------------------------------------------------------------------------------- /js/common/NavigatorHeader.js: -------------------------------------------------------------------------------- 1 | // NavigatorHeader.js 2 | 3 | import React, { 4 | Component, 5 | PropTypes, 6 | } from 'react'; 7 | 8 | import { 9 | StyleSheet, 10 | View, 11 | Text, 12 | PixelRatio, 13 | TouchableOpacity, 14 | } from 'react-native'; 15 | 16 | import Svg, { 17 | Circle, 18 | G, 19 | Path, 20 | Polygon, 21 | } from 'react-native-svg'; 22 | 23 | class Back extends Component { 24 | render(){ 25 | return ( 26 | 27 | 28 | 29 | 30 | 31 | ); 32 | } 33 | } 34 | 35 | export default class NavigatorHeader extends Component { 36 | 37 | static propTypes = { 38 | ...View.propTypes, 39 | title:PropTypes.string, 40 | titleView:PropTypes.func, 41 | leftBarButtonItem:PropTypes.func, 42 | rightBarButtonItems:PropTypes.func, 43 | isBelongTopNavigator:PropTypes.bool, 44 | onBackClick:PropTypes.func, 45 | }; 46 | 47 | _onPress = ()=>{ 48 | if (this.props.onBackClick) { 49 | this.props.onBackClick(); 50 | } 51 | } 52 | 53 | static defaultProps = { 54 | title:"", 55 | leftBarButtonItem:()=>,//()=>(), 56 | isBelongTopNavigator:false, 57 | rightBarButtonItems:()=>(), 58 | onBackClick:()=>{}, 59 | } 60 | 61 | render(){ 62 | 63 | const {leftBarButtonItem, title, titleView, rightBarButtonItems, isBelongTopNavigator} = this.props; 64 | 65 | return ( 66 | 67 | 68 | 69 | 70 | {this.props.leftBarButtonItem()} 71 | 72 | 73 | 74 | {titleView? titleView():({this.props.title})} 75 | 76 | 77 | {rightBarButtonItems()} 78 | 79 | 80 | 81 | 82 | ); 83 | } 84 | 85 | } 86 | 87 | 88 | const styles = StyleSheet.create({ 89 | container:{ 90 | height:64, 91 | backgroundColor:'#ccc', 92 | }, 93 | statusBar:{ 94 | height:20, 95 | backgroundColor:'white', 96 | }, 97 | barStyle:{ 98 | // flex:1, 99 | height:43, 100 | // marginTop:10, 101 | backgroundColor:'white', 102 | // marginBottom:2, 103 | flexDirection:'row', 104 | // flexWrap:'wrap', 105 | justifyContent:'center', 106 | alignItems:'center', 107 | 108 | }, 109 | leftNavBarButtonStyle:{ 110 | flex:1, 111 | padding: 5, 112 | }, 113 | centerViewStyle:{ 114 | flex:4, 115 | // justifyContent:'center', 116 | // marginTop:20, 117 | alignItems:'center', 118 | // marginBottom:20, 119 | }, 120 | rightNavBarButtonStyle:{ 121 | flex:1, 122 | }, 123 | dividerStyle:{ 124 | height: 1/PixelRatio.get(), 125 | backgroundColor: '#b2b2b2', 126 | }, 127 | leftTitle:{ 128 | // margin:10, 129 | textAlign:"center", 130 | alignItems:"center" 131 | }, 132 | title:{ 133 | color:"#ff5942", 134 | fontSize:17, 135 | margin:10, 136 | // marginTop:14, 137 | // fontWeight:"600", 138 | textAlign:"center", 139 | alignItems:"center" 140 | }, 141 | 142 | 143 | 144 | }); 145 | -------------------------------------------------------------------------------- /js/Cell/MerchantCell.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from "react"; 2 | 3 | import { View, Text, Image, StyleSheet, Dimensions, PixelRatio, Platform, TouchableOpacity, TouchableHighlight } from "react-native"; 4 | import Img from '../common/Img'; 5 | import Stars from '../svg/Stars'; 6 | const screenWidth = Dimensions.get('window').width; 7 | const screenHeight = Dimensions.get('window').height; 8 | 9 | export default class MerchantCell extends Component { 10 | 11 | static propTypes = { 12 | ...View.propTypes, 13 | onPress:PropTypes.func, 14 | source:Image.propTypes.source, 15 | logo:PropTypes.string,//商品图片地址 16 | shopname:PropTypes.string,//商品名,注意JSON里面为shopname 17 | catname:PropTypes.string,//分类 18 | level:PropTypes.oneOfType([PropTypes.string, PropTypes.number]),//星级 19 | cases:PropTypes.string,//图库 20 | activities:PropTypes.string,//优惠 21 | 22 | }; 23 | 24 | static defaultProps = { 25 | onPress:()=>{}, 26 | level:0, 27 | catname:"", 28 | cases:"", 29 | activities:"", 30 | 31 | }; 32 | 33 | _onPress = ()=>{ 34 | this.props.onPress && this.props.onPress() 35 | } 36 | render() { 37 | const { source, logo, shopname, catname, level, cases, activities} = this.props; 38 | return ( 39 | 45 | 46 | 47 | {/**/} 48 | {/**/} 49 | 50 | 51 | 52 | 53 | 54 | 55 | {shopname} 56 | 57 | 58 | 59 | 60 | 61 | {catname} 62 | 63 | 64 | {"图库"+cases} 65 | {"优惠"+activities} 66 | 67 | 68 | 69 | 70 | 71 | ); 72 | } 73 | } 74 | 75 | const styles = StyleSheet.create({ 76 | container: { 77 | flex: 1, 78 | height: 103, 79 | padding: 12, 80 | flexDirection: 'row', 81 | 82 | borderBottomColor:"#ebebeb", 83 | borderBottomWidth:1/PixelRatio.get(), 84 | }, 85 | cover:{ 86 | height:79, 87 | width:79, 88 | marginRight:11, 89 | borderRadius:3 90 | }, 91 | coverContainer:{ 92 | marginRight:11, 93 | // backgroundColor:"#dedede" 94 | }, 95 | titleContainer:{ 96 | marginLeft:-4, 97 | paddingHorizontal:4 98 | }, 99 | title:{ 100 | paddingTop:Platform.os === 'iOS'?2:0, 101 | fontSize:15, 102 | color:"#151515" 103 | }, 104 | info:{ 105 | flexDirection:"row", 106 | marginTop:Platform.os === 'iOS'?7:5 107 | }, 108 | infoText:{ 109 | marginRight:10, 110 | fontSize:11, 111 | color:"#666" 112 | }, 113 | infoCount:{ 114 | color:"#ff5942" 115 | }, 116 | stars:{ 117 | marginLeft:1 118 | } 119 | }); 120 | -------------------------------------------------------------------------------- /ios/Marry/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /js/Cell/AlbumCell.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from "react"; 2 | 3 | import { View, Text, Image, StyleSheet, Dimensions, PixelRatio, Platform, TouchableOpacity, TouchableHighlight } from "react-native"; 4 | import Img from '../common/Img'; 5 | 6 | const screenWidth = Dimensions.get('window').width; 7 | const screenHeight = Dimensions.get('window').height; 8 | 9 | const CellType = { 10 | "WIDE": "wide", // 婚宴酒店, 婚礼策划 11 | "TALL": "tall", // 婚纱摄影, 新娘跟妆, 婚纱礼服 12 | "STANDARD": "standard", // 珠宝钻戒, 主持跟拍, 婚礼百货 13 | } 14 | 15 | export default class AlbumCell extends Component { 16 | static propTypes = { 17 | cellType: PropTypes.string, 18 | onPress: PropTypes.func, 19 | title: PropTypes.string, 20 | detailTitle: PropTypes.string, 21 | source: Image.propTypes.source, 22 | } 23 | static defaultProps = { 24 | cellType: CellType.WIDE, 25 | } 26 | _onPress = ()=>{ 27 | this.props.onPress && this.props.onPress() 28 | } 29 | render() { 30 | let imageStyle = styles.imageWideStyle; 31 | let titleStyle = styles.titleWideStyle; 32 | let detailTitleStyle = styles.detailTitleWideStyle; 33 | const { source, title, detailTitle } = this.props; 34 | switch (this.props.cellType) { 35 | case CellType.WIDE: 36 | imageStyle=styles.imageWideStyle; 37 | break; 38 | case CellType.TALL: 39 | imageStyle=styles.imageTallStyle; 40 | titleStyle=styles.titleTallStyle; 41 | detailTitleStyle=styles.detailTitleTallStyle; 42 | break; 43 | default: 44 | imageStyle=styles.imageWideStyle; 45 | } 46 | return ( 47 | 52 | 53 | 54 | 55 | 56 | {title} 57 | 58 | 59 | 60 | 61 | 62 | {detailTitle} 63 | 64 | 65 | 66 | 67 | 68 | ); 69 | } 70 | } 71 | 72 | const styles = StyleSheet.create({ 73 | imageWideStyle: { 74 | borderRadius: 5, 75 | width: screenWidth - 20, 76 | height: 150*(screenWidth - 20)/300, 77 | }, 78 | titleWideStyle: { 79 | width: screenWidth - 20, 80 | height: 25, 81 | fontSize: 18, 82 | color: '#666', 83 | }, 84 | detailTitleWideStyle: { 85 | width: screenWidth - 20, 86 | height: 20, 87 | fontSize: 15, 88 | color: '#666', 89 | }, 90 | 91 | imageTallStyle: { 92 | borderRadius: 5, 93 | width: (screenWidth-40)/2, 94 | height: 350/270*(screenWidth-40)/2, 95 | }, 96 | titleTallStyle: { 97 | width: (screenWidth-40)/2, 98 | height: 25, 99 | fontSize: 18, 100 | color: '#666', 101 | }, 102 | detailTitleTallStyle: { 103 | width: (screenWidth-40)/2, 104 | height: 20, 105 | fontSize: 15, 106 | color: '#666', 107 | }, 108 | 109 | imageStandardStyle: { 110 | borderRadius: 5, 111 | width: (screenWidth-40)/2, 112 | height: 350/270*(screenWidth-40)/2, 113 | }, 114 | titleStandardStyle: { 115 | width: (screenWidth-40)/2, 116 | height: 25, 117 | fontSize: 18, 118 | color: '#666', 119 | }, 120 | detailTitleStandardStyle: { 121 | width: (screenWidth-40)/2, 122 | height: 20, 123 | fontSize: 15, 124 | color: '#666', 125 | }, 126 | }); 127 | -------------------------------------------------------------------------------- /js/components/ChannelSvgButton.js: -------------------------------------------------------------------------------- 1 | import React, { 2 | Component, 3 | PropTypes, 4 | } from 'react'; 5 | 6 | import { 7 | View, 8 | Text, 9 | TouchableOpacity, 10 | StyleSheet, 11 | } from 'react-native'; 12 | 13 | import Svg, { 14 | Circle, 15 | G, 16 | Path, 17 | Polygon, 18 | } from 'react-native-svg'; 19 | 20 | const circleRadius = 44; 21 | const kWidth = 24; 22 | const kHeight = 24; 23 | 24 | // const colorOfCircle='pink'; 25 | // const fillColor = '#fff'; 26 | const SVG_PATH_HLCH = 'M25.3,25.3c-0.8,0.8-1.8,1-2.3,0.5l0,0l0,0l-10.2-7.4l5.6-5.6l7.4,10.2l0,0C26.2,23.4,26,24.5,25.3,25.3z M8.5,17c-2.1,0-4-0.8-5.5-2L15,3c1.3,1.5,2,3.4,2,5.5C17,13.2,13.2,17,8.5,17z M0,8.5C0,3.8,3.8,0,8.5,0c2.1,0,4,0.8,5.5,2.1 l-12,12C0.8,12.6,0,10.6,0,8.5z'; 27 | // const svgPath = SVG_PATH_HLCH; 28 | 29 | export default class ChannelSvgButton extends Component { 30 | 31 | static propTypes = { 32 | // ...View.propTypes, 33 | ...TouchableOpacity.propTypes, 34 | containerStyle: View.propTypes.style, 35 | svgPath: PropTypes.string, 36 | colorOfCircle:PropTypes.string, 37 | fillColor:PropTypes.string, 38 | title: PropTypes.string, 39 | titleStyle:Text.propTypes.style, 40 | buttonTag:PropTypes.string, 41 | onPress:PropTypes.func, 42 | }; 43 | 44 | constructor(props) { 45 | super(props); 46 | } 47 | 48 | _onClick = ()=>{ 49 | if (this.props.onPress) { 50 | // alert(1) 51 | this.props.onPress(); 52 | } 53 | else { 54 | alert(2); 55 | } 56 | }; 57 | 58 | 59 | 60 | render() { 61 | // 获取title, containerStyle等属性 62 | let {title, titleStyle, svgPath, fillColor, colorOfCircle, containerStyle} = this.props; 63 | if (!titleStyle) { 64 | titleStyle = styles.buttonText; 65 | } 66 | if (!fillColor) { 67 | fillColor = '#fff'; 68 | } 69 | if (!colorOfCircle) { 70 | colorOfCircle = 'pink'; 71 | } 72 | if (!svgPath) { 73 | svgPath = ''; 74 | } 75 | return ( 76 | // onPress={()=>{alert(0)}} 77 | 81 | 82 | 86 | 87 | 88 | 94 | {/* 95 | x={9} 96 | y={9} 97 | 10=(circleRadius-kWidthd)/2; 98 | 然后再微小调整 99 | */} 100 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | {/*this.props.titleStyle与titleStyle不同*/} 116 | 117 | {/*this.props.title与title有区别*/} 118 | {this.props.title} 119 | 120 | 121 | 122 | 123 | 124 | ); 125 | } 126 | 127 | 128 | } 129 | 130 | const styles = StyleSheet.create({ 131 | container:{ 132 | flex: 1, 133 | backgroundColor:'#fff', 134 | // margin: 0,//失效 135 | alignItems:'center', 136 | }, 137 | boxTd:{ 138 | flex:1, 139 | // margin:5,//无效 140 | // height:88, 141 | // flexDirection:'column',//默认 142 | justifyContent:'center', 143 | alignItems:'center', 144 | }, 145 | button:{ 146 | overflow:'hidden', 147 | }, 148 | buttonText:{ 149 | marginBottom:10, 150 | fontSize:12, 151 | // color:'#fff', 152 | // fontFamily:'FZXiHei--YS1-0', 153 | textAlign:'center', 154 | }, 155 | }); 156 | -------------------------------------------------------------------------------- /webcell.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react'; 2 | import ReactNative, { 3 | Navigator, 4 | View, 5 | Text, 6 | Image, 7 | TouchableOpacity, 8 | StyleSheet, 9 | Dimensions, 10 | } from 'react-native'; 11 | 12 | 13 | const kScreenWidth = Dimensions.get('window').width; 14 | const kScreenHeight = Dimensions.get('window').height; 15 | 16 | const CellType = { 17 | Img_Text_4 : "Img_Text_4", 18 | Text_5 : "Text_5", 19 | Text_Blue_5 : "Text_Blue_5", 20 | Text_GrayBg_4 : "Text_GrayBg_4", 21 | Text_Blue_4 : "Text_Blue_4", 22 | Img_Text_5 : "Img_Text_5" 23 | } 24 | 25 | export default class WebView extends Component { 26 | static propTypes = { 27 | cellType: PropTypes.string, 28 | onPress: PropTypes.func, 29 | title: PropTypes.string, 30 | detailTitle: PropTypes.string, 31 | source: Image.propTypes.source, 32 | } 33 | 34 | static defaultProps = { 35 | cellType: CellType.Text_5, 36 | } 37 | 38 | _onPress = ()=> { 39 | console.log("_onPress"); 40 | const {onPress} = this.props; 41 | if (onPress) { 42 | onPress(); 43 | } 44 | } 45 | 46 | render() { 47 | let containerStyle = styles.container; 48 | let buttonStyle = styles.buttonStyle; 49 | let imageStyle = styles.imageLeftStyle; 50 | let titleStyle = styles.titleStyle; 51 | const { source, title } = this.props; 52 | switch (this.props.cellType) { 53 | case CellType.Img_Text_4: 54 | 55 | break; 56 | case CellType.Text_5: 57 | containerStyle = {width: kScreenWidth/5, height: 30, backgroundColor: '#e7e7e7',} 58 | break; 59 | case CellType.Text_Blue_5: 60 | containerStyle = {width: kScreenWidth/5, height: 30, backgroundColor: '#e7e7e7',} 61 | titleStyle = {flex: 1, fontSize: 12, textAlign: 'center', color: 'rgb(14, 140, 226)'} 62 | break; 63 | case CellType.Text_GrayBg_4: 64 | containerStyle = {padding: 3, width: kScreenWidth/4, height: 30, backgroundColor: 'white'} 65 | buttonStyle = {flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center', backgroundColor: '#e7e7e7'} 66 | break; 67 | case CellType.Text_Blue_4: 68 | 69 | break; 70 | case CellType.Img_Text_5: 71 | containerStyle = {width: kScreenWidth/5, height: 60, backgroundColor: 'white'} 72 | buttonStyle = {flex: 1, padding: 5, justifyContent: 'center', alignItems: 'center'} 73 | imageStyle = styles.imageTopStyle 74 | break; 75 | default: 76 | 77 | } 78 | 79 | return ( 80 | 81 | 86 | {source && } 87 | 88 | {title} 89 | 90 | 91 | 92 | ); 93 | } 94 | } 95 | 96 | const styles = StyleSheet.create({ 97 | container: { 98 | width: kScreenWidth/4, 99 | height: 30, 100 | flexDirection: 'row', 101 | // justifyContent: 'center', 102 | // alignItems: 'center', 103 | backgroundColor: '#e7e7e7', 104 | 105 | // padding: 5, 106 | }, 107 | imageLeftStyle: { 108 | width: 20, 109 | height: 20, 110 | // paddingRight: 5, 111 | marginRight: 5, 112 | }, 113 | imageTopStyle: { 114 | width: 30, 115 | height: 30, 116 | marginBottom: 5, 117 | }, 118 | titleStyle: { 119 | flex: 1, 120 | fontSize: 12, 121 | textAlign: 'center', 122 | // backgroundColor: 'red', 123 | }, 124 | titleBlueStyle: {}, 125 | buttonStyle: { 126 | // padding: 5, 127 | // margin: 5, 128 | flex: 1, 129 | justifyContent: 'space-between', 130 | alignItems: 'center', 131 | backgroundColor: 'white', 132 | flexDirection: 'row', 133 | // marginLeft: 5, 134 | // marginRight: 5, 135 | padding: 8, 136 | }, 137 | buttonGrayBgStyle: { 138 | padding: 5, 139 | backgroundColor: 'gray', 140 | }, 141 | }); 142 | -------------------------------------------------------------------------------- /js/Cell/ActivityCell.js: -------------------------------------------------------------------------------- 1 | // ActivityCell.js 2 | // 用于优惠活动的cell 3 | 4 | import React, { Component, PropTypes } from "react"; 5 | 6 | import { View, Text, Image, StyleSheet, Dimensions, Platform, TouchableOpacity, TouchableHighlight } from "react-native"; 7 | import Img from '../common/Img'; 8 | const screenWidth = Dimensions.get('window').width; 9 | const screenHeight = Dimensions.get('window').height; 10 | 11 | const cellPadding = 10; 12 | const cellHeight_I5 = 380; 13 | const textHeight = 35; 14 | const cellHeight = cellHeight_I5*screenWidth/640; 15 | const imageHeight = cellHeight - textHeight - cellPadding; 16 | const imageWidth = screenWidth - 2*cellPadding; 17 | 18 | export default class ActivityCell extends Component{ 19 | 20 | static propTypes = { 21 | ...View.propTypes, 22 | onPress:PropTypes.func, 23 | source:Image.propTypes.source, 24 | title:PropTypes.string, 25 | cover:PropTypes.string,//商品图片地址 26 | shopname:PropTypes.string,//商品名,注意JSON里面为shopname 27 | shopId:PropTypes.string, 28 | }; 29 | 30 | 31 | _didSelectedCell = ()=>{ 32 | const {shopId} = this.props; 33 | if (shopId && shopId !== "") 34 | { 35 | this.props.onPress(shopId); 36 | }else { 37 | alert(1); 38 | } 39 | } 40 | 41 | _renderCell=()=>{ 42 | const { source, cover, title, shopname, shopId } = this.props; 43 | return ( 44 | 45 | 46 | 47 | 48 | {/**/} 49 | {/**/} 50 | 51 | 52 | 53 | 54 | 55 | 56 | {/* 57 | (i.Text,{numberOfLines:2,style:[c.title,n?c.simpleTitle:c.additionalTitle]},t.title),!n&& 58 | (i.Text,{style:c.shopName},t.shopName), 59 | */} 60 | 61 | {title} 62 | {shopname} 63 | 64 | 65 | 66 | 67 | 马上报名 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | ); 76 | } 77 | 78 | 79 | 80 | 81 | render(){ 82 | return this._renderCell(); 83 | } 84 | } 85 | 86 | const styles = StyleSheet.create({ 87 | container:{ 88 | paddingHorizontal:10, 89 | paddingVertical:10, 90 | // marginBottom:7.5, 91 | // width:win.width 92 | }, 93 | gap:{ 94 | backgroundColor:"#fff", 95 | shadowColor:"#e0e0e0", 96 | // shadowOpacity:1, 97 | shadowRadius:2, 98 | shadowOffset:{ 99 | width:0, 100 | height:0 101 | } 102 | }, 103 | contentContainerStyle:{ 104 | flex:1, 105 | flexDirection:"row" 106 | }, 107 | cover:{ 108 | width:148, 109 | height:90, 110 | borderRadius:3 111 | }, 112 | content:{ 113 | flex:1, 114 | marginLeft:9.5 115 | }, 116 | title:{ 117 | height:40, 118 | color:"#151515", 119 | fontSize:15, 120 | lineHeight:20 121 | }, 122 | simpleTitle:{ 123 | marginTop:4, 124 | marginBottom:17, 125 | height:44, 126 | lineHeight:Platform.OS === "ios"? 20:22 127 | }, 128 | additionalTitle:{ 129 | marginTop:Platform.OS === "ios"? -2:0//-4:0 130 | }, 131 | shopName:{ 132 | color:"#8a8888", 133 | fontSize:12, 134 | height:Platform.OS === "ios"? 16:14,//12:14 135 | marginVertical:Platform.OS === "ios"? 9:6 136 | }, 137 | button:{ 138 | height:24, 139 | width:77, 140 | backgroundColor:"#ff5942", 141 | borderRadius:4, 142 | alignItems:"center", 143 | justifyContent:"center" 144 | }, 145 | buttonText:{ 146 | color:"#fff", 147 | fontSize:12 148 | } 149 | }); 150 | -------------------------------------------------------------------------------- /js/common/Checker.js: -------------------------------------------------------------------------------- 1 | import React,{ 2 | Component, 3 | PropTypes, 4 | } from 'react'; 5 | 6 | import ReactNative,{ 7 | View, 8 | StyleSheet, 9 | Text, 10 | Image, 11 | TouchableOpacity, 12 | } from 'react-native'; 13 | 14 | import Svg, { 15 | Circle, 16 | G, 17 | Path, 18 | Polygon, 19 | Polyline, 20 | } from 'react-native-svg'; 21 | 22 | 23 | const kEmptyImage = require('../../images/404.png'); 24 | const kLoadingImage = require('../../images/loading.gif'); 25 | 26 | export default class Checker extends Component { 27 | 28 | static propTypes = { 29 | onReload:PropTypes.func, 30 | state:PropTypes.number.isRequired, 31 | }; 32 | 33 | _onload = ()=>{ 34 | if (onReload) { 35 | onReload(); 36 | } 37 | }; 38 | 39 | 40 | render() { 41 | const {onReload, state} = this.props; 42 | const defaultProps = { 43 | state: 0, 44 | }; 45 | 46 | switch (state) { 47 | case 1: 48 | return ( 49 | 50 | 51 | ); 52 | break; 53 | case 0: 54 | return ( 55 | 56 | 61 | 70 | 78 | 83 | 84 | 85 | 哎唷出错啦~刷新试试~ 86 | 87 | 88 | 92 | 100 | 108 | 109 | 110 | 111 | 点我刷新 112 | 113 | 114 | 115 | ); 116 | 117 | break; 118 | case -1: 119 | return ( 120 | 121 | 122 | 123 | ); 124 | 125 | 126 | break; 127 | case -2: 128 | return ( 129 | 130 | 131 | 内容还在筹备中哦,敬请期待~ 132 | 133 | ); 134 | break; 135 | default: 136 | return (null); 137 | } 138 | 139 | } 140 | 141 | } 142 | 143 | const styles = StyleSheet.create({ 144 | container:{ 145 | flex:1, 146 | alignItems:"center", 147 | justifyContent:"center", 148 | backgroundColor:"#fff", 149 | }, 150 | text:{ 151 | fontSize:13, 152 | color:"#aaa", 153 | }, 154 | error:{ 155 | alignItems:"center", 156 | justifyContent:"center", 157 | }, 158 | errorText:{ 159 | fontSize:13, 160 | color:"#aaa", 161 | }, 162 | warningImage:{ 163 | marginVertical:15, 164 | }, 165 | refresh:{ 166 | height:30, 167 | width:133.5, 168 | marginTop:25, 169 | borderRadius:4.5, 170 | borderWidth:1, 171 | borderColor:"#ff5942", 172 | }, 173 | refreshContent:{ 174 | flexDirection:"row", 175 | alignItems:"center", 176 | justifyContent:"center", 177 | }, 178 | refreshText:{ 179 | color:"#ff5942", 180 | fontSize:13, 181 | }, 182 | }); 183 | -------------------------------------------------------------------------------- /js/svg/Logo.js: -------------------------------------------------------------------------------- 1 | // Logo.js 2 | import React, { Component } from 'react'; 3 | 4 | import { 5 | View, 6 | Text, 7 | StyleSheet 8 | } from 'react-native'; 9 | 10 | import Svg, { 11 | Circle, 12 | G, 13 | Path, 14 | Polygon, 15 | } from 'react-native-svg'; 16 | 17 | export default class Logo extends Component { 18 | render(){ 19 | return ( 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /js/views/MerchantDetail.js: -------------------------------------------------------------------------------- 1 | // MerchantDetail.js 2 | // 商品详情 3 | 4 | import React, { Component } from "react"; 5 | import { InteractionManager, ScrollView, View, Text, Image, StyleSheet, ListView, RefreshControl, TouchableOpacity } from "react-native"; 6 | 7 | import NavigatorHeader from "../common/NavigatorHeader"; 8 | import DetailHeader from "../components/DetailHeader"; 9 | import ScrollableTabView, { DefaultTabBar, ScrollableTabBar } from "react-native-scrollable-tab-view"; 10 | import MerchantDetailCell from '../Cell/MerchantDetailCell'; 11 | import AlbumCell from '../Cell/AlbumCell'; 12 | // 图库默认数据请求URL 13 | const url_album = "http://newapi.deyi.com/wedding/api/caselist"; 14 | // 排序URL 15 | const url_sort = "http://newapi.deyi.com/wedding/api/casecondition"; 16 | const kHostAlbumUrl = url_album; 17 | const url_request = { 18 | method: 'POST', 19 | body:JSON.stringify({ 20 | // "areaid": 0, 21 | // "catid": categories.defaultId, 22 | "page": 1 23 | }) 24 | } 25 | 26 | let resultsCache = { 27 | albumlist: [], 28 | activitylist: [], 29 | }; 30 | 31 | export default class MerchantDetail extends Component { 32 | constructor(props) { 33 | super(props); 34 | const ds = new ListView.DataSource({ 35 | rowHasChanged:(r1, r2) => r1 !== r2, 36 | }); 37 | this.state = { 38 | shopid: "", 39 | shopname: "", 40 | source: null, 41 | isRefreshing: true, 42 | renderPlaceholderOnly: true, 43 | dataSourceOfAlbum: ds.cloneWithRows([{}, {}, {}, {}]), 44 | dataSourceOfActivity: ds.cloneWithRows([{}, {}, {}, {}]), 45 | }; 46 | } 47 | componentDidMount() { 48 | InteractionManager.runAfterInteractions(() => { 49 | this.setState({ 50 | renderPlaceholderOnly: false, 51 | shopid: this.props.shopid, 52 | shopname: this.props.shopname, 53 | source: this.props.source, 54 | }); 55 | this._onRefresh(); 56 | }); 57 | } 58 | _onRefresh = ()=> { 59 | this._getNetworkData(); 60 | console.log(this.state.isRefreshing); 61 | } 62 | _getNetworkData = ()=>{ 63 | 64 | fetch(url_album,url_request) 65 | .then((response)=>response.json()) 66 | .then((responseData)=>{ 67 | 68 | resultsCache.albumlist = responseData.data.list; 69 | console.log("resultsCache.albumlist: "+resultsCache.albumlist); 70 | 71 | this.setState({ 72 | isRefreshing:false, 73 | dataSourceOfAlbum:this.state.dataSourceOfAlbum.cloneWithRows(resultsCache.albumlist), 74 | }); 75 | }) 76 | .catch((error)=>{ 77 | resultsCache.albumlist = Array(2); 78 | this.setState({ 79 | isRefreshing:false, 80 | dataSourceOfAlbum:this.state.dataSourceOfAlbum.cloneWithRows(resultsCache.albumlist), 81 | }); 82 | }) 83 | } 84 | _renderAlbumRow = (rowData)=>{ 85 | return (); 86 | } 87 | _renderActivityRow = (rowData)=>{ 88 | return ( 89 | 90 | ); 91 | } 92 | _renderHeader = ()=>{ 93 | return ( 94 | 95 | 98 | 99 | 100 | ); 101 | } 102 | _renderSeparator = (sectionID, rowID, adjacentRowHighlighted)=>{ 103 | return (); 104 | } 105 | 106 | render() { 107 | return ( 108 | 109 | 110 | 111 | 120 | } 121 | dataSource={this.state.dataSourceOfAlbum} 122 | renderRow={this._renderAlbumRow} 123 | renderSectionHeader={()=>} 124 | renderHeader={this._renderHeader} 125 | renderSeparator={this._renderSeparator} 126 | /> 127 | 128 | 129 | 免费咨询 130 | 131 | 132 | ); 133 | } 134 | } 135 | 136 | const styles = StyleSheet.create({ 137 | container: { 138 | flex: 1, 139 | }, 140 | button: { 141 | height: 49, 142 | backgroundColor: '#ff5942', 143 | justifyContent: 'center', 144 | alignItems: 'center', 145 | position: 'absolute', 146 | bottom: 0, 147 | left: 0, 148 | right: 0, 149 | }, 150 | buttonText: { 151 | fontSize: 18, 152 | color: 'white', 153 | }, 154 | 155 | }); 156 | -------------------------------------------------------------------------------- /js/tabs/Album.js: -------------------------------------------------------------------------------- 1 | // Album.js 2 | // 图库 3 | 4 | import React, { Component, PropTypes } from 'react'; 5 | import { InteractionManager, View, StyleSheet, Text, ListView, RefreshControl, Dimensions, TouchableOpacity, TouchableHighlight, Animated, Easing } from 'react-native'; 6 | import { connect } from 'react-redux'; 7 | 8 | import FaceIcon from '../svg/FaceIcon'; 9 | import NavigatorHeader from '../common/NavigatorHeader'; 10 | import FilterHeaderView from '../views/FilterHeaderView'; 11 | import SplitView from '../common/SplitView'; 12 | import AlbumCell from '../Cell/AlbumCell'; 13 | import Checker from '../common/Checker'; 14 | 15 | import { fetchAlbumData } from '../actions/album'; 16 | 17 | import * as categories from "../data/categories"; 18 | import * as sortBys from "../data/sortBys"; 19 | 20 | const screenWidth = Dimensions.get('window').width; 21 | const screenHeight = Dimensions.get('window').height; 22 | 23 | // 图库默认数据请求URL 24 | const url_album = "http://newapi.deyi.com/wedding/api/caselist"; 25 | // 排序URL 26 | const url_sort = "http://newapi.deyi.com/wedding/api/casecondition"; 27 | const kHostAlbumUrl = url_album; 28 | const url_request = { 29 | method: 'POST', 30 | body:JSON.stringify({ 31 | // "areaid": 0, 32 | // "catid": categories.defaultId, 33 | "page": 1 34 | }) 35 | } 36 | 37 | let resultsCache = { 38 | albumlist:[], 39 | }; 40 | 41 | class Album extends Component { 42 | 43 | constructor(props) { 44 | super(props); 45 | const ds = new ListView.DataSource({ 46 | rowHasChanged: (r1, r2)=>r1 !== r2 47 | }); 48 | this.state = { 49 | isShowFilterView: false, 50 | isRefreshing: true, 51 | renderPlaceholderOnly: true, 52 | fadeAnim: new Animated.Value(-screenWidth), // init opacity 0 53 | transitionFromRight: new Animated.Value(-screenWidth), 54 | }; 55 | this.dataSource = ds; 56 | } 57 | 58 | componentDidMount() { 59 | InteractionManager.runAfterInteractions(() => { 60 | this.setState({renderPlaceholderOnly: false}); 61 | this._onRefresh(); 62 | }); 63 | } 64 | 65 | _onRefresh = ()=>{ 66 | // this._getNetworkData(); 67 | const { dispatch } = this.props; 68 | dispatch(fetchAlbumData()); 69 | } 70 | 71 | _getNetworkData = ()=>{ 72 | 73 | fetch(url_album,url_request) 74 | .then((response)=>response.json()) 75 | .then((responseData)=>{ 76 | 77 | resultsCache.albumlist = responseData.data.list; 78 | console.log("resultsCache.albumlist: "+resultsCache.albumlist); 79 | // ERROR!错误! 80 | // this.setState = { 81 | // isRefreshing:false, 82 | // dataSource:this.state.dataSource.cloneWithRows(["r 0", "r 1", "r2", "r3", "r4"]), 83 | // }; 84 | this.setState({ 85 | isRefreshing:false, 86 | dataSource:this.state.dataSource.cloneWithRows(resultsCache.albumlist), 87 | }); 88 | }) 89 | .catch((error)=>{ 90 | resultsCache.albumlist = Array(2); 91 | this.setState({ 92 | isRefreshing:false, 93 | dataSource:this.state.dataSource.cloneWithRows(resultsCache.albumlist), 94 | }); 95 | }) 96 | } 97 | 98 | _renderRow = (rowData)=> { 99 | return (); 100 | } 101 | 102 | render() { 103 | console.log("render Album"); 104 | const {album} = this.props; 105 | var contentView; 106 | 107 | if (album.isError) { 108 | contentView = 109 | } 110 | else if (album.isChangedOption) { 111 | contentView = 112 | } 113 | else if (album.list.length === 0) { 114 | contentView = 115 | } 116 | else { 117 | contentView = 118 | 130 | } 131 | /> 132 | } 133 | return ( 134 | 135 | (武汉)} title={"图库"}/> 136 | 140 | {contentView} 141 | 142 | ); 143 | } 144 | } 145 | 146 | const styles = StyleSheet.create({ 147 | container: { 148 | flex: 1, 149 | // justifyContent: 'center', 150 | // alignItems: 'center', 151 | // backgroundColor: '#2D2E3F', 152 | backgroundColor: 'white', 153 | }, 154 | }); 155 | 156 | 157 | function mapStateToProps(state) { 158 | const { album } = state; 159 | return { 160 | album 161 | } 162 | } 163 | 164 | export default connect(mapStateToProps)(Album) 165 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | 3 | import com.android.build.OutputFile 4 | 5 | /** 6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets 7 | * and bundleReleaseJsAndAssets). 8 | * These basically call `react-native bundle` with the correct arguments during the Android build 9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the 10 | * bundle directly from the development server. Below you can see all the possible configurations 11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the 12 | * `apply from: "../../node_modules/react-native/react.gradle"` line. 13 | * 14 | * project.ext.react = [ 15 | * // the name of the generated asset file containing your JS bundle 16 | * bundleAssetName: "index.android.bundle", 17 | * 18 | * // the entry file for bundle generation 19 | * entryFile: "index.android.js", 20 | * 21 | * // whether to bundle JS and assets in debug mode 22 | * bundleInDebug: false, 23 | * 24 | * // whether to bundle JS and assets in release mode 25 | * bundleInRelease: true, 26 | * 27 | * // whether to bundle JS and assets in another build variant (if configured). 28 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants 29 | * // The configuration property can be in the following formats 30 | * // 'bundleIn${productFlavor}${buildType}' 31 | * // 'bundleIn${buildType}' 32 | * // bundleInFreeDebug: true, 33 | * // bundleInPaidRelease: true, 34 | * // bundleInBeta: true, 35 | * 36 | * // the root of your project, i.e. where "package.json" lives 37 | * root: "../../", 38 | * 39 | * // where to put the JS bundle asset in debug mode 40 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", 41 | * 42 | * // where to put the JS bundle asset in release mode 43 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release", 44 | * 45 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 46 | * // require('./image.png')), in debug mode 47 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", 48 | * 49 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 50 | * // require('./image.png')), in release mode 51 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", 52 | * 53 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means 54 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to 55 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle 56 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ 57 | * // for example, you might want to remove it from here. 58 | * inputExcludes: ["android/**", "ios/**"] 59 | * ] 60 | */ 61 | 62 | apply from: "../../node_modules/react-native/react.gradle" 63 | 64 | /** 65 | * Set this to true to create two separate APKs instead of one: 66 | * - An APK that only works on ARM devices 67 | * - An APK that only works on x86 devices 68 | * The advantage is the size of the APK is reduced by about 4MB. 69 | * Upload all the APKs to the Play Store and people will download 70 | * the correct one based on the CPU architecture of their device. 71 | */ 72 | def enableSeparateBuildPerCPUArchitecture = false 73 | 74 | /** 75 | * Run Proguard to shrink the Java bytecode in release builds. 76 | */ 77 | def enableProguardInReleaseBuilds = false 78 | 79 | android { 80 | compileSdkVersion 23 81 | buildToolsVersion "23.0.1" 82 | 83 | defaultConfig { 84 | applicationId "com.marry" 85 | minSdkVersion 16 86 | targetSdkVersion 22 87 | versionCode 1 88 | versionName "1.0" 89 | ndk { 90 | abiFilters "armeabi-v7a", "x86" 91 | } 92 | } 93 | splits { 94 | abi { 95 | reset() 96 | enable enableSeparateBuildPerCPUArchitecture 97 | universalApk false // If true, also generate a universal APK 98 | include "armeabi-v7a", "x86" 99 | } 100 | } 101 | buildTypes { 102 | release { 103 | minifyEnabled enableProguardInReleaseBuilds 104 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 105 | } 106 | } 107 | // applicationVariants are e.g. debug, release 108 | applicationVariants.all { variant -> 109 | variant.outputs.each { output -> 110 | // For each separate APK per architecture, set a unique version code as described here: 111 | // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits 112 | def versionCodes = ["armeabi-v7a":1, "x86":2] 113 | def abi = output.getFilter(OutputFile.ABI) 114 | if (abi != null) { // null for the universal-debug, universal-release variants 115 | output.versionCodeOverride = 116 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode 117 | } 118 | } 119 | } 120 | } 121 | 122 | dependencies { 123 | compile fileTree(dir: "libs", include: ["*.jar"]) 124 | compile "com.android.support:appcompat-v7:23.0.1" 125 | compile "com.facebook.react:react-native:+" // From node_modules 126 | } 127 | 128 | // Run this once to be able to run the application with BUCK 129 | // puts all compile dependencies into folder libs for BUCK to use 130 | task copyDownloadableDepsToLibs(type: Copy) { 131 | from configurations.compile 132 | into 'libs' 133 | } 134 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /js/tabs/Merchant.js: -------------------------------------------------------------------------------- 1 | // Merchant.js 2 | // 商家 3 | 4 | import React, { Component, PropTypes } from 'react'; 5 | import { InteractionManager, View, StyleSheet, Text, ListView, RefreshControl, Dimensions, TouchableOpacity, TouchableHighlight, Animated, Easing } from 'react-native'; 6 | import { connect } from 'react-redux'; 7 | 8 | import FaceIcon from '../svg/FaceIcon'; 9 | import NavigatorHeader from '../common/NavigatorHeader'; 10 | 11 | import FilterHeaderView from '../views/FilterHeaderView'; 12 | import MerchantCell from '../Cell/MerchantCell'; 13 | 14 | import SplitView from '../common/SplitView'; 15 | 16 | import Checker from '../common/Checker'; 17 | 18 | import { fetchMerchantData } from '../actions/merchant'; 19 | 20 | import * as categories from "../data/categories"; 21 | 22 | import * as areas from "../data/areas"; 23 | 24 | 25 | const screenWidth = Dimensions.get('window').width; 26 | const screenHeight = Dimensions.get('window').height; 27 | 28 | 29 | const url_shoplist = "http://newapi.deyi.com/wedding/api/shoplist"; 30 | const url_request = { 31 | method: 'POST', 32 | body:JSON.stringify({ 33 | "areaid": 0, 34 | "catid": categories.defaultId, 35 | "page": 1 36 | }) 37 | } 38 | 39 | let resultsCache = { 40 | shoplist:[], 41 | }; 42 | 43 | class Merchant extends Component { 44 | constructor(props) { 45 | super(props); 46 | const ds = new ListView.DataSource({ 47 | rowHasChanged: (r1, r2)=>r1 !== r2, 48 | 49 | }); 50 | this.state = { 51 | isShowFilterView: false, 52 | dataSource: ds.cloneWithRows([{}, {}]), 53 | // transitionFromLeft 54 | renderPlaceholderOnly: true, 55 | fadeAnim: new Animated.Value(-screenWidth), // init opacity 0 56 | transitionFromRight: new Animated.Value(-screenWidth), 57 | isRefreshing: true, 58 | }; 59 | this.dataSource = ds; 60 | } 61 | componentDidMount() { 62 | InteractionManager.runAfterInteractions(() => { 63 | this.setState({renderPlaceholderOnly: false}); 64 | this._onRefresh(); 65 | }); 66 | } 67 | 68 | _onRefresh = ()=>{ 69 | // this._getNetworkData(); 70 | const {dispatch} = this.props; 71 | dispatch(fetchMerchantData()); 72 | } 73 | 74 | _getNetworkData = ()=>{ 75 | 76 | fetch(url_shoplist,url_request) 77 | .then((response)=>response.json()) 78 | .then((responseData)=>{ 79 | 80 | resultsCache.shoplist = responseData.data.shoplist; 81 | console.log("resultsCache.activity: "+resultsCache.shoplist); 82 | // ERROR!错误! 83 | // this.setState = { 84 | // isRefreshing:false, 85 | // dataSource:this.state.dataSource.cloneWithRows(["r 0", "r 1", "r2", "r3", "r4"]), 86 | // }; 87 | this.setState({ 88 | isRefreshing:false, 89 | dataSource:this.state.dataSource.cloneWithRows(resultsCache.shoplist), 90 | }); 91 | }) 92 | .catch((error)=>{ 93 | resultsCache.shoplist = Array(2); 94 | this.setState({ 95 | isRefreshing:false, 96 | dataSource:this.state.dataSource.cloneWithRows(resultsCache.shoplist), 97 | }); 98 | }) 99 | } 100 | 101 | _onPressLeft = ()=>{ 102 | this.setState({ 103 | isShowFilterView: !this.state.isShowFilterView, 104 | }); 105 | this._showFilterView() 106 | } 107 | _onPressRight = ()=>{ 108 | this.setState({ 109 | isShowFilterView: !this.state.isShowFilterView, 110 | }); 111 | this._showFilterView() 112 | } 113 | _showFilterView = ()=>{ 114 | 115 | Animated.timing( // Uses easing functions 116 | this.state.fadeAnim, // The value to drive 117 | { 118 | toValue: 0, // Target 119 | duration: 300, // Configuration 120 | }, 121 | ).start(); // Don't forget start! 122 | } 123 | _hideFilterView = ()=>{ 124 | Animated.timing( // Uses easing functions 125 | this.state.fadeAnim, // The value to drive 126 | { 127 | toValue: -screenWidth, // Target 128 | duration: 300, // Configuration 129 | }, 130 | ).start(); // Don't forget start! 131 | } 132 | 133 | _renderRow = (rowData)=>{ 134 | return (); 135 | } 136 | render() { 137 | console.log("render Merchant"); 138 | const {merchant} = this.props; 139 | var contentView; 140 | 141 | if (merchant.isError) { 142 | contentView = 143 | } 144 | else if (merchant.isChangedOption) { 145 | contentView = 146 | } 147 | else if (merchant.list.length === 0) { 148 | contentView = 149 | } 150 | else { 151 | contentView = 152 | 163 | } 164 | /> 165 | } 166 | return ( 167 | 168 | (武汉)} title={"商家"}/> 169 | 170 | 176 | 177 | {contentView} 178 | {/* 179 | 180 | 181 | 182 | 183 | 184 | 185 | */} 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | ); 194 | } 195 | } 196 | 197 | const styles = StyleSheet.create({ 198 | container: { 199 | flex: 1, 200 | // backgroundColor: '#2D2E3F', 201 | backgroundColor: 'white', 202 | }, 203 | mask: { 204 | position: 'absolute', 205 | // left: -screenWidth, 206 | // right: screenWidth, 207 | top: 64+40, 208 | bottom: 0, 209 | width: screenWidth, 210 | backgroundColor: 'rgba(55, 55, 55, 0.5)', 211 | }, 212 | }); 213 | 214 | function mapStateToProps(state) { 215 | const { merchant } = state; 216 | return { 217 | merchant 218 | } 219 | } 220 | 221 | export default connect(mapStateToProps)(Merchant) 222 | -------------------------------------------------------------------------------- /js/tabs/Home.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react'; 2 | import { Dimensions, View, StyleSheet, Text, ListView, ScrollView, RefreshControl, PixelRatio } from 'react-native'; 3 | import { connect } from 'react-redux'; 4 | 5 | import NavigatorHeader from '../common/NavigatorHeader'; 6 | import FaceIcon from '../svg/FaceIcon'; 7 | import Logo from '../svg/Logo'; 8 | import TravelIconType from '../svg/TravelIcon'; 9 | import Channels from '../components/Channels'; 10 | import HourglassLoading from '../../HourglassLoading'; 11 | import SectionHeaderView from '../common/SectionHeaderView'; 12 | import MerchantDetailCell from '../Cell/MerchantDetailCell'; 13 | import AlbumCell from '../Cell/AlbumCell'; 14 | import ActivityCell from '../Cell/ActivityCell'; 15 | import ActivityDetailView from '../detail/ActivityDetailView'; 16 | 17 | import {fetchHomeData} from '../actions/home'; 18 | 19 | const screenWidth = Dimensions.get('window').width; 20 | const screenHeight = Dimensions.get('window').height; 21 | 22 | let resultsCache = { 23 | activity:[], 24 | shop:[], 25 | cases:[], 26 | }; 27 | const url_home = "http://newapi.deyi.com/wedding/api/index"; 28 | const url_request = { 29 | method:'POST', 30 | body:JSON.stringify({ 31 | 32 | }), 33 | } 34 | 35 | class Home extends Component { 36 | 37 | constructor(props) { 38 | super(props); 39 | const ds = new ListView.DataSource({ 40 | rowHasChanged: (r1, r2)=>r1 !== r2, 41 | }); 42 | this.state = { 43 | isLoading:false, 44 | isRefreshing: true, 45 | dataSourceOfActivities: ds.cloneWithRows([{}]), 46 | dataSourceOfMerchants: ds.cloneWithRows([{}, {}, {}]), 47 | dataSourceOfAlbum: ds.cloneWithRows([{}, {}, {}, {}, {}, {}, {}]), 48 | }; 49 | this.dataSourceOfActivities = ds; 50 | this.dataSourceOfMerchants = ds; 51 | this.dataSourceOfAlbum = ds; 52 | 53 | } 54 | componentDidMount() { 55 | this._onRefresh(); 56 | } 57 | _onRefresh = ()=>{ 58 | // this._getNetworkData(); 59 | const {dispatch} = this.props; 60 | dispatch(fetchHomeData()); 61 | }; 62 | _getNetworkData = ()=>{ 63 | 64 | fetch(url_home,url_request) 65 | .then((response)=>response.json()) 66 | .then((responseData)=>{ 67 | 68 | resultsCache.activity = responseData.data.activity; 69 | resultsCache.shop = responseData.data.shop; 70 | resultsCache.cases = responseData.data.cases; 71 | console.log("resultsCache.activity: "+resultsCache.activity); 72 | console.log("resultsCache.shop: "+resultsCache.shop); 73 | // ERROR!错误! 74 | // this.setState = { 75 | // isRefreshing:false, 76 | // dataSource:this.state.dataSource.cloneWithRows(["r 0", "r 1", "r2", "r3", "r4"]), 77 | // }; 78 | this.setState({ 79 | isRefreshing:false, 80 | dataSourceOfActivities:this.state.dataSourceOfActivities.cloneWithRows(resultsCache.activity), 81 | dataSourceOfMerchants:this.state.dataSourceOfMerchants.cloneWithRows(resultsCache.shop), 82 | dataSourceOfAlbum: this.state.dataSourceOfAlbum.cloneWithRows(resultsCache.cases), 83 | }); 84 | }) 85 | .catch((error)=>{ 86 | resultsCache.activity = Array(2); 87 | resultsCache.shop = Array(4); 88 | resultsCache.cases = []; 89 | this.setState({ 90 | isRefreshing:false, 91 | dataSourceOfActivities:this.state.dataSourceOfActivities.cloneWithRows(resultsCache.activity), 92 | dataSourceOfMerchants:this.state.dataSourceOfMerchants.cloneWithRows(resultsCache.shop), 93 | dataSourceOfAlbum: this.state.dataSourceOfAlbum.cloneWithRows(resultsCache.cases), 94 | }); 95 | }) 96 | } 97 | _renderActivityRow = (rowData) => { 98 | const {navigator} = this.props; 99 | return ( 100 | navigator.push({component: ActivityDetailView})} 108 | /> 109 | ); 110 | } 111 | _renderMerchantRow = (rowData) => { 112 | return ( 113 | {this.props.navigator.push({routeId: 'MerchantDetail', params: {source:{uri:rowData.logo}, level: rowData.level, shopid: rowData.shopid, shopname: rowData.shopname} })}} 121 | /> 122 | ); 123 | } 124 | _renderHeader = ()=> { 125 | const {home} = this.props; 126 | return ( 127 | 128 | 129 | } 134 | enableEmptySections={true} 135 | /> 136 | 137 | 144 | 145 | 146 | 147 | 148 | ); 149 | } 150 | _renderAlbumRow = (rowData, sectionID, rowID, highlightRow) => { 151 | // return ( 152 | // 153 | // 154 | // _renderAlbumRow 155 | // 156 | // 157 | // ); 158 | return (); 159 | } 160 | _renderSeparator = (sectionID, rowID, adjacentRowHighlighted)=>{ 161 | return (); 162 | } 163 | render() { 164 | console.log('render Home'); 165 | const {home, actions} = this.props; 166 | return ( 167 | 168 | (武汉)} titleView={()=>}/> 169 | 182 | } 183 | /> 184 | 185 | 186 | ); 187 | } 188 | } 189 | 190 | const styles = StyleSheet.create({ 191 | container: { 192 | flex: 1, 193 | // justifyContent: 'center', 194 | // alignItems: 'center', 195 | backgroundColor: '#f6f6f6', 196 | // backgroundColor: 'white', 197 | }, 198 | scrollViewContainer: { 199 | flex: 1 200 | }, 201 | }); 202 | 203 | function mapStateToProps(state) { 204 | const { home } = state; 205 | return { 206 | home 207 | } 208 | } 209 | 210 | export default connect(mapStateToProps)(Home) 211 | -------------------------------------------------------------------------------- /js/common/SplitView.js: -------------------------------------------------------------------------------- 1 | // SplitView.js 2 | // 两个ListView,左边控制右边显示 3 | 4 | // __d("marry/views/Filters/FiltersCategory.js", 5 | // function(e,t,n,r){ 6 | // Object.defineProperty(r,"__esModule",{value:!0}); 7 | // var i=t("react-native/Libraries/react-native/react-native.js"), 8 | // o=babelHelpers.interopRequireDefault(i), 9 | // a=t("marry/components/Link.js"), 10 | // s=babelHelpers.interopRequireDefault(a), 11 | // u=t("marry/components/LoopView.js"), 12 | // l=babelHelpers.interopRequireDefault(u), 13 | // c=t("lodash/index.js"), 14 | // p=babelHelpers.interopRequireDefault(c), 15 | // f=i.StyleSheet.create({}), 16 | // h=function(e){ 17 | // function t(){ 18 | // babelHelpers.classCallCheck(this,t); 19 | // var e=babelHelpers.possibleConstructorReturn(this,Object.getPrototypeOf(t).apply(this,arguments)); 20 | // // e._getChildren=function(t){ 21 | // // var n=e._categories[t],r=n.children.slice(); 22 | // // return n["default"]||r.unshift({id:n.id,title:"\u5168\u90e8"+n.title+"\u5546\u5bb6"}), 23 | // // e._ds.cloneWithRows(r) 24 | // // }, 25 | // // e._category=function(t){ 26 | // // e.setState({active:t,children:e._getChildren(t)}) 27 | // // }, 28 | // // e._select=function(t,n){ 29 | // // e.setState({selected:n,children:e._getChildren(e.state.active)}), 30 | // // e.props.onChange(t,n) 31 | // // }, 32 | // e._renderParentRow=function(t,n){ 33 | // var r=n==e.state.active; 34 | // return o["default"].createElement(s["default"],{style:[f.parent,r&&f.active],contentContainerStyle:f.parentContainer,underlayColor:"rgba(255, 255, 255, 0.5)",onPress:e._category.bind(e,n)}, 35 | // o["default"].createElement(i.View,{style:[f.activeContainer,r&&f.activeTextContainer]}, 36 | // o["default"].createElement(i.Text,{style:[f.text,r&&f.activeText]},t.title))) 37 | // }, 38 | // e._renderChildRow=function(t){ 39 | // return o["default"].createElement(s["default"],{style:f.child,underlayColor:"rgba(255, 255, 255, 0.5)",contentContainerStyle:f.childContainer,onPress:e._select.bind(e,t.title,t.id)}, 40 | // o["default"].createElement(i.Text,{style:[f.text,e.state.selected==t.id&&f.textSelected]},t.title)) 41 | // }; 42 | // var n=p["default"].cloneDeep(e.props.data); 43 | // e._ds=new i.ListView.DataSource({rowHasChanged:function(e,t){return e.id!==t.id}}); 44 | // var r=0; 45 | // return p["default"].every(n,function(t,n){ 46 | // var i=t.children,o=t.id;return o===e.props.selected?(r=n,!1):p["default"].find(i,{id:e.props.selected})?(r=n,!1):!0}), 47 | // e._categories=n,e.state={parent:n,children:e._getChildren(r),active:r,selected:e.props.selected},e} 48 | // return babelHelpers.inherits(t,e),babelHelpers.createClass(t,[{key:"render",value:function(){return o["default"].createElement(i.View,babelHelpers["extends"]({},this.props,{style:f.container}),o["default"].createElement(l["default"],{style:f.cateContainer,data:this.state.parent,renderRow:this._renderParentRow}),o["default"].createElement(i.ListView,{style:f.itemContainer,dataSource:this.state.children,renderRow:this._renderChildRow,pageSize:8}))}}]),t}(i.Component);h.displayName="FiltersCategory",r["default"]=h}), 49 | 50 | import React, { Component, PropTypes } from 'react'; 51 | import { Animated, View, StyleSheet, Text, ListView, Dimensions, PixelRatio, TouchableOpacity, TouchableHighlight } from 'react-native'; 52 | 53 | import CommonCell from './CommonCell'; 54 | 55 | import * as categories from "../data/categories"; 56 | 57 | const screenWidth = Dimensions.get('window').width; 58 | const screenHeight = Dimensions.get('window').height; 59 | 60 | export default class SplitView extends Component { 61 | _getChildren = (index)=> { 62 | // var n=e._categories[t],r=n.children.slice(); 63 | const item = categories[index]; 64 | const children = item.slice(); 65 | // return n["default"]||r.unshift({id:n.id,title:"\u5168\u90e8"+n.title+"\u5546\u5bb6"}), 66 | // e._ds.cloneWithRows(r) 67 | // this.ds.cloneWithRows(r) 68 | return item || children.unshift({id: item.id, title:"全部"+item.title+"商家"}) 69 | 70 | } 71 | _category = (index)=>{ 72 | this.setState({active:index,children:this._getChildren(index)}) 73 | } 74 | _select = (t, index)=>{ 75 | this.setState({ 76 | selected:index, 77 | children:this._getChildren(this.state.active) 78 | }) 79 | this.props.onChange && this.props.onChange(t, index) 80 | } 81 | _renderParentRow = (rowData, index)=>{ 82 | var r = index===this.state.active; 83 | 84 | return ( 85 | { 91 | return ( 92 | 95 | 96 | {rowData.title} 97 | 98 | 99 | ) 100 | }} 101 | /> 102 | ); 103 | } 104 | 105 | _renderChildRow = (rowData)=>{ 106 | // return o["default"].createElement(s["default"],{style:f.child,underlayColor:"rgba(255, 255, 255, 0.5)",contentContainerStyle:f.childContainer,onPress:e._select.bind(e,t.title,t.id)}, 107 | // o["default"].createElement(i.Text,{style:[f.text,e.state.selected==t.id&&f.textSelected]},t.title)) 108 | return ( 109 | { 115 | 118 | {rowData.title} 119 | 120 | }} 121 | /> 122 | ); 123 | } 124 | 125 | static propTypes = { 126 | ...View.propTypes, 127 | datas: PropTypes.array, 128 | leftSelectedIndex: PropTypes.number, 129 | rightSelectedIndex: PropTypes.number, 130 | } 131 | static defaultProps = { 132 | datas: [{}], 133 | } 134 | constructor(props) { 135 | super(props); 136 | 137 | const ds = new ListView.DataSource({ 138 | rowHasChanged: (r1, r2) => r1!==r2, 139 | }); 140 | this.state={ 141 | active: 0, 142 | selected: 0, 143 | dataSourceOfLeft: ds.cloneWithRows([{}, {}, {}]), 144 | dataSourceOfRight: ds.cloneWithRows([{}, {}, {}, {}, {}, {}]), 145 | } 146 | } 147 | _renderLeftListViewRow = (rowData)=>{ 148 | return ( 149 | alert(1)} underlayColor='#dbdbdb'> 150 | 151 | 152 | 153 | XXXX 154 | 155 | 156 | ); 157 | } 158 | _renderRightListViewRow = (rowData)=>{ 159 | return ( 160 | alert(1)} underlayColor='#dbdbdb'> 161 | 162 | XXXX 163 | 164 | 165 | ); 166 | } 167 | render(){ 168 | const { style } = this.props; 169 | return ( 170 | alert(0)}> 171 | {/* 172 | 173 | 174 | 175 | 176 | 177 | */} 178 | 179 | 186 | 187 | 192 | 193 | 194 | ); 195 | } 196 | } 197 | 198 | 199 | const styles = StyleSheet.create({ 200 | container: { 201 | flex: 1, 202 | flexDirection:"row", 203 | backgroundColor:"#fff" 204 | }, 205 | maskButton: { 206 | position: 'absolute', 207 | top: 0, bottom: 0, 208 | left: 0, right: 0, 209 | // backgroundColor: 'green', 210 | }, 211 | leftContainer: { 212 | width: screenWidth/2, 213 | backgroundColor: 'white' 214 | }, 215 | rightContainer: { 216 | width: screenWidth/2, 217 | backgroundColor: 'white' 218 | }, 219 | cateContainer: { 220 | flex:1, 221 | backgroundColor:"#f7f7f7" 222 | }, 223 | itemContainer: { 224 | flex:1, 225 | backgroundColor:"#fff" 226 | }, 227 | parent: { 228 | height:39, 229 | backgroundColor: 'white', 230 | }, 231 | parentContainer: { 232 | justifyContent:"center", 233 | alignItems:"center", 234 | backgroundColor: 'white' 235 | }, 236 | text: { 237 | color:"#666", 238 | fontSize:13 239 | }, 240 | textSelected: { 241 | color:"#ff5942" 242 | }, 243 | activeContainer: { 244 | paddingLeft:12, 245 | borderLeftWidth:2.5, 246 | borderLeftColor:"transparent" 247 | }, 248 | child: { 249 | height:39, 250 | marginLeft:6, 251 | borderBottomColor:"#ebebeb", 252 | borderBottomWidth:1/PixelRatio.get() 253 | }, 254 | childContainer: { 255 | justifyContent:"center", 256 | alignItems:"center" 257 | }, 258 | active: { 259 | backgroundColor:"#fff" 260 | }, 261 | activeText: { 262 | color:"#ff5942" 263 | }, 264 | activeTextContainer: { 265 | borderLeftColor:"#ff5942" 266 | } 267 | }); 268 | -------------------------------------------------------------------------------- /js/components/Channels.js: -------------------------------------------------------------------------------- 1 | // 首页中的8个图标 2 | import React,{ 3 | Component, 4 | } from 'react'; 5 | 6 | import { 7 | StyleSheet, 8 | Text, 9 | View, 10 | Image, 11 | Navigator, 12 | } from 'react-native'; 13 | 14 | import ChannelSvgButton from './ChannelSvgButton'; 15 | 16 | import Album from '../tabs/Album'; 17 | import MerchantDetail from '../views/MerchantDetail'; 18 | 19 | // 婚宴酒店 #f88 id:268,type:"wide" 20 | const SVG_PATH_HYJD = 'M21.9,13.2c-1.1-0.3-1.3-0.7-1.2-1.7c0-2.4-1.2-3.6-3.5-3.7c-0.7,0-1.4,0-2.3,0c1-1.2,1.9-2.1,2.6-3.1 c1-1.4,0.9-2.6,0-3.6c-1-1.1-2.3-1.2-3.7-0.2c-0.5,0.4-0.7,0.4-1.2,0c-1.4-1-2.7-0.9-3.7,0.2c-1,1-1,2.2,0,3.7 c0.7,1.1,1.6,1.9,2.7,3.1c-0.7,0-1.2,0-1.6,0c-3.4,0-4.3,0.9-4.4,4.3c0,0.8-0.4,0.8-1,1c-3.1,0.8-5.1,3.9-3.8,6.7 c0.8,1.7,0.9,3.3,0.9,5.1c0,1,0.4,1.2,1.2,1.2c6.8,0,13.6,0,20.4,0c1.1,0,1.2-0.4,1.2-1.3c0-1.3-0.3-2.6,0.4-3.9 C26.7,17.7,25.3,14,21.9,13.2z M8.1,11c0-0.5,0.5-0.5,0.9-0.5c1.4,0,2.7,0,4.1,0c1.4,0,2.7,0,4.1,0c0.4,0,0.9,0,0.9,0.5 c0,0.6-0.4,0.7-0.9,0.7c-2.7,0-5.4,0-8.2,0C8.5,11.7,8,11.6,8.1,11z M23.1,18.6c-0.2,1.2-1.3,2.2-2.6,2.2c-1.7-0.1-2.8-1-3.7-2.4 c-2.9,3.2-5,3.2-7.7-0.1c-0.8,1.3-1.8,2.2-3.2,2.4c-1.5,0.2-2.8-0.7-3-2.1c-0.2-1.5,0.6-2.7,2.2-3c0.3-0.1,0.6-0.1,0.9-0.1 c4.7,0,9.3,0,14,0c0.4,0,0.9,0.1,1.3,0.2C22.7,16.1,23.3,17.2,23.1,18.6z'; 21 | // 婚纱摄影 #fccb46 id:366,type:"tall" 22 | const SVG_PATH_HSSY = 'M22.8,23.3H3.2c-1.8,0-3.2-1.4-3.2-3.2V7.5c0-1.8,1.4-3.2,3.2-3.2h6.9l1.8-2.8c0.1-0.2,0.4-0.3,0.6-0.3h7.1 c0.2,0,0.5,0.2,0.6,0.3l1.8,2.8h0.7c1.8,0,3.2,1.4,3.2,3.2v12.7C26,21.9,24.6,23.3,22.8,23.3z M15.5,5.9c-4.4,0-7.9,3.5-7.9,7.9 c0,4.4,3.5,7.9,7.9,7.9c4.4,0,7.9-3.5,7.9-7.9C23.5,9.5,19.9,5.9,15.5,5.9z M15.5,19.1c-2.9,0-5.3-2.4-5.3-5.3 c0-2.9,2.4-5.3,5.3-5.3c2.9,0,5.3,2.4,5.3,5.3C20.8,16.8,18.5,19.1,15.5,19.1z M7.6,3.7H2.5c-0.4,0-0.6-0.3-0.6-0.6V2.4 c0-0.4,0.3-0.6,0.6-0.6h5.1c0.4,0,0.6,0.3,0.6,0.6v0.6C8.2,3.4,8,3.7,7.6,3.7z'; 23 | // 珠宝钻戒 #87c5fb id:359,type:"standard" 24 | const SVG_PATH_ZBZJ = 'M22.7,26H3.3C1.5,26,0,24.5,0,22.7V3.3C0,1.5,1.5,0,3.3,0h19.3C24.5,0,26,1.5,26,3.3v19.3 C26,24.5,24.5,26,22.7,26z M23.8,3.2c0-0.4-0.3-0.7-0.7-0.7H2.9c-0.4,0-0.7,0.3-0.7,0.7v13.9c0,0.4,0.3,0.7,0.7,0.7h20.2 c0.4,0,0.7-0.3,0.7-0.7L23.8,3.2L23.8,3.2z M13,26c-4,0-7.3-3.3-7.3-7.3S9,11.5,13,11.5s7.3,3.2,7.3,7.3C20.3,22.7,17,26,13,26z M13,14.1 c-2.6,0-4.7,2.1-4.7,4.7c0,2.6,2.1,4.7,4.7,4.7c2.6,0,4.7-2.1,4.7-4.7C17.7,16.1,15.6,14.1,13,14.1z M14.3,8.3c-0.7,0-0.9,0.3-1.3,0.7c-0.3-0.4-0.6-0.7-1.3-0.7c-0.7,0-1.3,0.5-1.3,1.3c0,0.5,0.2,0.9,0.7,1.3 l1.8,1.8H13h0.1l1.8-1.8c0.4-0.4,0.7-0.9,0.7-1.3C15.5,8.8,15,8.3,14.3,8.3z'; 25 | // 婚礼策划 #fe8dc0 id:296,type:"wide" 26 | const SVG_PATH_HLCH = 'M25.3,25.3c-0.8,0.8-1.8,1-2.3,0.5l0,0l0,0l-10.2-7.4l5.6-5.6l7.4,10.2l0,0C26.2,23.4,26,24.5,25.3,25.3z M8.5,17c-2.1,0-4-0.8-5.5-2L15,3c1.3,1.5,2,3.4,2,5.5C17,13.2,13.2,17,8.5,17z M0,8.5C0,3.8,3.8,0,8.5,0c2.1,0,4,0.8,5.5,2.1 l-12,12C0.8,12.6,0,10.6,0,8.5z'; 27 | 28 | const Section_0_SVG_Paths = [{title:'婚宴酒店', id:'268',type:'wide', fillColor:'#f88', path:SVG_PATH_HYJD}, 29 | {title:'婚纱摄影', id:'366',type:'tall', fillColor:'#fccb46', path:SVG_PATH_HSSY}, 30 | {title:'珠宝钻戒', id:'359',type:'standard', fillColor:'#87c5fb', path:SVG_PATH_ZBZJ}, 31 | {title:'婚礼策划', id:'296',type:'wide', fillColor:'#fe8dc0', path:SVG_PATH_HLCH},]; 32 | 33 | 34 | 35 | // 新娘跟妆 #87c5fb id:374,type:"tall" 36 | const SVG_PATH_XNGZ = 'M20.4,26h-6.3c-1,0-1.7-0.8-1.7-1.7v-8c0-0.9,0.6-1.6,1.5-1.7v-4.4C13.8,9.5,14.4,9,15,9h4.5 c0.6,0,1.2,0.5,1.2,1.2v4.4c0.8,0.1,1.5,0.8,1.5,1.7v8C22.2,25.2,21.4,26,20.4,26z M20.7,17.2c0-0.4-0.3-0.7-0.7-0.7 c-0.4,0-0.7,0.3-0.7,0.7v6.5c0,0.4,0.3,0.7,0.7,0.7c0.4,0,0.7-0.3,0.7-0.7V17.2z M20.2,6.9C20.2,7.5,19.7,8,19,8H16 c-0.6,0-1.2-0.5-1.2-1.2V3.7c0-0.1,0-0.1,0-0.2l0,0c0,0-0.2-1.1,1-2C17,0.7,18.3,0.1,18.7,0c0,0,1.5-0.2,1.5,1s0,4,0,4l0,0V6.9z M6.6,17.5c-1.6,0-2.9-0.4-2.9-0.8c0-0.4,1-0.7,2.3-0.8v-8C5.7,7.6,5.4,7.3,5.4,6.9V2.2c0-0.6,0.5-1.1,1.1-1.1h0.2 c0.6,0,1.1,0.5,1.1,1.1v4.6c0,0.4-0.2,0.8-0.6,0.9v8c1.3,0.1,2.3,0.4,2.3,0.8C9.5,17.1,8.2,17.5,6.6,17.5z M6.6,18.8 c1,0,1.9-0.3,2.5-0.8c0.1,0.3,0.2,0.7,0.2,1.1l-0.7,6C8.5,25.6,8.1,26,7.7,26H5.5c-0.4,0-0.8-0.4-0.8-0.8l-0.7-6 c-0.1-0.4,0-0.8,0.2-1.1C4.7,18.5,5.6,18.8,6.6,18.8z'; 37 | // 主持跟拍 #a7e173 id:375,type:"standard" 38 | const SVG_PATH_ZCGP = 'M24.8,23.3c-2.4,0.8-5,0.8-7.4,0c-0.2-0.1-0.4-0.2-0.5-0.3c-1.6,0.9-3.5,1.4-5.5,1.4C5.1,24.5,0,19.4,0,13.1 C0,6.8,5.1,1.8,11.4,1.8c6.3,0,11.3,5.1,11.3,11.3c0,3.1-1.3,5.9-3.3,8c1.5,0.3,3.1,0.2,4.5-0.3c0.7-0.2,1.5,0,1.9,0.6 C26.2,22.1,25.8,23,24.8,23.3z M11.4,22.3c1.8,0,3.2-1.5,3.2-3.2s-1.5-3.2-3.2-3.2S8.1,17.3,8.1,19S9.6,22.3,11.4,22.3z M13,13.1 c0-0.9-0.7-1.6-1.6-1.6c-0.9,0-1.6,0.7-1.6,1.6c0,0.9,0.7,1.6,1.6,1.6C12.3,14.7,13,14,13,13.1z M5.4,9.9c-1.8,0-3.2,1.5-3.2,3.2 c0,1.8,1.5,3.2,3.2,3.2s3.2-1.5,3.2-3.2C8.7,11.3,7.2,9.9,5.4,9.9z M11.4,3.9c-1.8,0-3.2,1.5-3.2,3.2c0,1.8,1.5,3.2,3.2,3.2 s3.2-1.5,3.2-3.2C14.6,5.4,13.2,3.9,11.4,3.9z M20.6,13.1c0-1.8-1.5-3.2-3.2-3.2s-3.2,1.5-3.2,3.2c0,1.8,1.5,3.2,3.2,3.2 S20.6,14.9,20.6,13.1z'; 39 | // 婚纱礼服 #fccb46 id:380,type:"tall" 40 | const SVG_PATH_HSLF = 'M25.5,21.4c0,0-0.1,0.9-1.6,1.6c-1.5,0.7-3.9,1.3-4.2,1c-0.2-0.2-0.2-7-2.1-8.8c0,0-1.1-0.6-1,0.5 s2,1.7,2.1,8.8c0,0.1-0.1,0.2-0.1,0.2c-0.1,0.1-0.4,0.2-1,0.4c-1.4,0.4-3.3,0.6-4.7,0.5c-1.4,0-3.3-0.1-4.7-0.5 c-0.6-0.2-0.9-0.3-1-0.4c0,0-0.1,0-0.1-0.2c0-7.1,2-7.8,2.1-8.8c0-1.1-1-0.5-1-0.5c-1.9,1.8-1.9,8.6-2.1,8.8c-0.2,0.2-2.7-0.3-4.2-1 c-1.5-0.7-1.6-1.6-1.6-1.6c0.3-8.4,8.9-13,8.9-13c0.2-0.3-0.6-0.8-1.6-2.6c-0.9-1.7-0.1-2.5,1.7-3C9.4,2.7,9.3,2.5,9.3,2.4V0.8 C9.3,0.4,9.7,0,10.1,0s0.8,0.4,0.8,0.8v1.6c0,0.1,0,0.2-0.1,0.3C12.2,2.7,13,3.7,13,3.8c0-0.1,0.8-1,2.1-1.1c0-0.1-0.1-0.2-0.1-0.3 V0.8c0-0.4,0.4-0.8,0.8-0.8s0.8,0.4,0.8,0.8v1.6c0,0.2-0.1,0.3-0.2,0.5c1.8,0.5,2.6,1.4,1.7,3c-0.9,1.8-1.8,2.3-1.6,2.6 C16.6,8.5,25.2,13,25.5,21.4z'; 41 | // 结婚图库 #ae93e5 id:0 42 | const SVG_PATH_JHTK = 'M23.5,24h-21C1.1,24,0,22.9,0,21.5V4c0-1.4,1.1-2.5,2.5-2.5h21C24.9,1.5,26,2.6,26,4v17.5 C26,22.9,24.9,24,23.5,24z M13,3.4c-5.2,0-9.4,4.2-9.4,9.4c0,5.2,4.2,9.4,9.4,9.4c5.2,0,9.4-4.2,9.4-9.4C22.4,7.6,18.2,3.4,13,3.4z M13.7,15.9c-0.6-1-0.2-2.2,0.7-2.8c1.3-0.7,2.1,0,2.7,0.9c1-0.5,2.1-0.7,2.8,0.6c0.6,1,0.2,2.2-0.8,2.8c-3.4,1.7-3.4,1.7-3.4,1.7 S15.7,19.1,13.7,15.9z M11.6,15.9c0,0,0,0-4.6-2.3c-1.3-0.7-1.8-2.4-1-3.7c1-1.6,2.4-1.4,3.7-0.7C10.5,8,11.6,7.1,13.3,8 c1.3,0.8,1.8,2.4,1,3.7C11.6,15.9,11.6,15.9,11.6,15.9z'; 43 | 44 | 45 | const Section_1_SVG_Paths = [{title:'新娘跟妆', id:'374',type:'tall', fillColor:'#87c5fb', path:SVG_PATH_XNGZ}, 46 | {title:'主持跟拍', id:'375',type:'standard', fillColor:'#a7e173', path:SVG_PATH_ZCGP}, 47 | {title:'婚纱礼服', id:'380',type:'tall', fillColor:'#fccb46', path:SVG_PATH_HSLF}, 48 | {title:'结婚图库', id:'0',type:'', fillColor:'#ae93e5', path:SVG_PATH_JHTK},]; 49 | 50 | const homeTabTag = 'Home'; 51 | const albumTabTag = 'Album'; 52 | const merchantTabTag = 'Merchant'; 53 | 54 | 55 | 56 | // 推荐页的8个选项 57 | export default class Channels extends Component { 58 | static propTypes = { 59 | ...View.propTypes, 60 | }; 61 | 62 | 63 | 64 | 65 | 66 | 67 | _renderButton(){ 68 | return ( 69 | 70 | 71 | ); 72 | } 73 | 74 | 75 | 76 | 77 | render() { 78 | const {navigator} = this.props; 79 | return ( 80 | 81 | 82 | 83 | { 84 | Section_0_SVG_Paths.map( 85 | (item, index)=>{ 86 | return ( 87 | { 92 | // global.root.setState({ 93 | // isHiddenTabBar:true, 94 | // }); 95 | console.log("Channel will push to Album"); 96 | if (navigator) { 97 | console.log("Channel push to Album"); 98 | navigator.push({ 99 | navigator: navigator, 100 | routeId: "MerchantDetail", 101 | component:Album, 102 | // message: '向右拖拽关闭页面', 103 | // sceneConfig: Navigator.SceneConfigs.FloatFromRight, 104 | }); 105 | } 106 | else { 107 | alert(item.id); 108 | } 109 | 110 | 111 | }} 112 | containerStyle={styles.entry} 113 | svgPath={item.path} 114 | /> 115 | ); 116 | } 117 | ) 118 | } 119 | 120 | 121 | 122 | { 123 | Section_1_SVG_Paths.map( 124 | (item, index)=>{ 125 | return ( 126 | {alert(item.id)}} containerStyle={styles.entry} svgPath={item.path}/> 127 | ); 128 | } 129 | ) 130 | } 131 | 132 | 133 | 134 | ); 135 | } 136 | } 137 | 138 | const styles = StyleSheet.create({ 139 | container:{ 140 | flex:1, 141 | backgroundColor:'#fff' 142 | }, 143 | menu:{ 144 | flex:1, 145 | flexDirection:"row", 146 | flexWrap:"wrap", 147 | // backgroundColor:'gray', 148 | // alignItems:'center', 149 | // justifyContent:'center', 150 | }, 151 | entry:{ 152 | flex:1, 153 | // width:375/4.0, 154 | height:88, 155 | alignItems:"center", 156 | justifyContent:"center", 157 | // backgroundColor:'green', 158 | }, 159 | text:{ 160 | fontSize:12, 161 | color:"#222" 162 | }, 163 | icon:{ 164 | width:40, 165 | height:40, 166 | borderRadius:20, 167 | marginBottom:12, 168 | alignItems:"center", 169 | justifyContent:"center" 170 | }, 171 | }); 172 | -------------------------------------------------------------------------------- /js/marry.js: -------------------------------------------------------------------------------- 1 | // marry.js 2 | import React, { Component, PropTypes } from 'react'; 3 | import ReactNative, { View, StyleSheet, Text, Navigator } from 'react-native'; 4 | 5 | const ReactNativeART = ReactNative.ART; 6 | const { 7 | Group, 8 | Shape, 9 | // Circle, 10 | Surface, 11 | Transform, 12 | Rectangle, 13 | } = ReactNativeART; 14 | 15 | import { bindActionCreators } from 'redux'; 16 | import { connect } from 'react-redux'; 17 | import * as Actions from './actions'; 18 | 19 | 20 | import Home from './tabs/Home'; 21 | import Album from './tabs/Album'; 22 | import Merchant from './tabs/Merchant'; 23 | import MerchantDetail from './views/MerchantDetail'; 24 | 25 | import TabNavigator from 'react-native-tab-navigator'; 26 | const TabNavigatorItem = TabNavigator.Item; 27 | 28 | import Logo from './svg/Logo'; 29 | import Back from './svg/Back'; 30 | 31 | const homeTabTag = 'Home'; 32 | const albumTabTag = 'Album'; 33 | const merchantTabTag = 'Merchant'; 34 | const defaultTabTag = homeTabTag; 35 | 36 | // 首页/推荐 tabItem SVG Paths 37 | const homeSVGPaths = [{path:'M13.3,0C7.6,0,2.9,4.7,2.9,10.5c0,1,0.1,2,0.4,3c1.4,5.7,9.2,11.8,9.5,12.1l0.6,0.4l0.5-0.4 c0.4-0.3,9.2-7.2,9.8-13.3v-0.2c0.1-0.5,0.1-1.1,0.1-1.6C23.8,4.7,19.1,0,13.3,0z M21.9,12.1l-0.1,0.9c-1,4.3-6.6,9.2-8.4,10.8 c-1.7-1.5-7.2-6.4-8.3-10.8c-0.2-0.8-0.4-1.6-0.4-2.5c0-4.8,3.9-8.7,8.7-8.7c4.8,0,8.7,3.9,8.7,8.7C22,11,21.9,11.6,21.9,12.1z'}, 38 | {path:'M16,6.4c-1.3,0-2.1,0.5-2.7,1.1c-0.6-0.6-1.4-1.1-2.7-1.1c-2,0-3.5,1.4-3.5,3.4c0,1.2,0.6,2.4,1.6,3.4 l3.9,3.8c0.1,0.2,0.4,0.3,0.6,0.3c0.2,0,0.5-0.1,0.7-0.3l3.9-3.8c1-1,1.6-2.2,1.6-3.4C19.5,7.8,18,6.4,16,6.4z M16.6,11.9 c0,0-2.5,2.5-3.3,3.2c-0.8-0.8-3.2-3.2-3.2-3.2c-0.7-0.7-1-1.4-1-2c0-0.9,0.6-1.5,1.7-1.5c0.9,0,1.1,0.3,1.8,1.1l0.1,0.1 c0.2,0.1,0.4,0.3,0.7,0.3c0.3,0,0.5-0.1,0.7-0.3l0.1-0.1c0.6-0.8,0.9-1.1,1.8-1.1c0.9,0,1.5,0.6,1.5,1.5 C17.6,10.5,17.2,11.3,16.6,11.9z'}]; 39 | 40 | // 图库 tabItem SVG Paths 41 | const albumSVGPaths = [{path:'M23.2,1H7C5.4,1,4.2,2.3,4.2,3.8V3L1.9,3.6C0.5,4-0.3,5.4,0.1,6.8l4.2,15.3v0.1c0,1.6,1.3,2.8,2.8,2.8h16.2 c1.5,0,2.8-1.3,2.7-2.9v-1.4v-1.4V3.8C26,2.3,24.7,1,23.2,1z M4.2,17L1.7,7.8C1.3,6.4,2.2,4.9,3.6,4.5l0.6-0.2l0,0V17z M24.7,20.8 c0,1.6-1.3,2.8-2.8,2.8H8.5c-1.5,0-2.8-1.3-2.8-2.8v-0.1L24.7,20.8L24.7,20.8L24.7,20.8z M24.7,19.4h-19V5.2c0-1.6,1.3-2.8,2.8-2.8 h13.4c1.6,0,2.8,1.3,2.8,2.8V19.4L24.7,19.4z'}, 42 | {path:'M10.9,10.9c1.8,0,3.2-1.4,3.2-3.2s-1.4-3.2-3.2-3.2S7.7,6,7.7,7.8S9.1,10.9,10.9,10.9z M10.9,6 c1,0,1.8,0.8,1.8,1.8s-0.8,1.8-1.8,1.8c-1,0-1.8-0.8-1.8-1.8S9.9,6,10.9,6z'}, 43 | {path:'M18.2,10.8c-0.1,0-0.1-0.1-0.1-0.1c-0.1-0.1-0.1-0.2-0.1-0.2c-0.3-0.3-0.7-0.3-1,0l-3.7,3.7l-1-1.1 C12,13,11.7,13,11.6,13l-0.1-0.1c-0.3-0.3-0.7-0.3-1,0l-2.3,2.5c-0.3,0.3-0.3,0.7,0,1c0.3,0.3,0.7,0.3,0.9,0l2.1-2.1l1.4,1.4 c0.3,0.3,0.7,0.3,1,0c0.1,0,0.2-0.1,0.3-0.1l3.4-3.4l4.2,4.2c0.3,0.3,0.7,0.3,1,0c0.3-0.3,0.3-0.7,0-1L18.2,10.8z'},]; 44 | 45 | // 商家 tabItem SVG Paths 46 | const merchantSVGPaths = [{path:'M26,6c0-1.6-1.3-2.9-2.9-2.9h-5.9C16.7,1.4,15,0.2,13,0.2c-2,0-3.6,1.3-4.1,2.9h-6C1.3,3.1,0,4.4,0,6v5h1.8 c-0.2,0.4-0.4,0.9-0.4,1.4v10.2c0,1.6,1.3,2.9,2.9,2.9h17.4c1.6,0,2.9-1.3,2.9-2.9V12.4c0-0.5-0.1-1-0.4-1.4H26V6z M12.9,1.7 c1.1,0,2,0.6,2.4,1.5h-4.8C10.9,2.3,11.9,1.7,12.9,1.7z M23.1,21.4c0,1.5-1.3,2.7-2.9,2.7H5.7c-1.6,0-2.9-1.2-2.9-2.7v-7.5 c0-1.5,1.3-2.7,2.9-2.7h14.5c1.6,0,2.9,1.2,2.9,2.7V21.4z M24.5,9.6H1.3V7.5c0-1.6,1.3-2.9,2.9-2.9h17.4c1.6,0,2.9,1.3,2.9,2.9V9.6 z'}, 47 | {path:'M15.3,12.9c-0.9,0-1.8,0.4-2.4,1.2c-0.6-0.7-1.4-1.2-2.4-1.2c-1.7,0-3,1.4-3,3.2c0,0.5,0.1,1,0.4,1.4 c1,1.6,4.6,5.3,4.8,5.5c0.1,0.1,0.2,0.1,0.2,0.1c0.1,0,0.1,0,0.2-0.1c0.2-0.2,3.8-3.9,4.8-5.5c0.2-0.4,0.4-0.8,0.4-1.4 C18.4,14.4,17,12.9,15.3,12.9z M16.8,16.8c-0.6,1-2.8,3.3-3.9,4.5C11.7,20,9.6,17.7,9,16.8c-0.1-0.2-0.2-0.4-0.2-0.6 c0-1,0.7-1.8,1.7-1.8c0.7,0,1.2,0.3,1.5,1c0.2,0.3,0.5,0.6,0.9,0.6c0.4,0,0.8-0.2,0.9-0.6c0.4-0.6,0.9-1,1.5-1 c0.9,0,1.8,0.8,1.8,1.8C17,16.3,17,16.6,16.8,16.8z'}]; 48 | 49 | 50 | 51 | export default class Marry extends Component { 52 | 53 | constructor(props) { 54 | super(props); 55 | this.state = { 56 | selectedTab: defaultTabTag, 57 | isHiddenTabBar: false, 58 | }; 59 | } 60 | 61 | // Missing parameter,用于不能缺省的参数 62 | throwIfMissing = ()=> { 63 | throw new Error('缺少参数'); 64 | } 65 | 66 | // TODO: 使用 Navigator 67 | _renderNavigatorContent = (routeId='', component=Home)=> { 68 | 69 | 70 | return ( 71 | { 77 | if (route.routeId === albumTabTag) { 78 | this.setState({ 79 | isHiddenTabBar: true, 80 | }); 81 | } 82 | const Comp = route.component; 83 | return 84 | } 85 | } 86 | 87 | configureScene={(route) => { 88 | // if (route.sceneConfig) { 89 | // return route.sceneConfig; 90 | // } 91 | return Navigator.SceneConfigs.FloatFromBottom; 92 | } 93 | } 94 | /> 95 | ); 96 | } 97 | 98 | _tabItemIcon = (selected=false, paths)=>{ 99 | return ( 100 | 105 | 106 | { 107 | paths.map( (item, index)=>{ 108 | return ( 109 | 113 | ); 114 | } ) 115 | } 116 | 117 | 118 | ); 119 | // return (); 120 | } 121 | 122 | // 渲染/设置 tabItem 123 | _renderTabItem = (title='Tab', tabTag=this.throwIfMissing(), renderIcon=this.throwIfMissing(), renderSelectedIcon, containerView=)=> { 124 | return ( 125 | this.setState({selectedTab:tabTag})} 130 | renderIcon={renderIcon} 131 | renderSelectedIcon={renderSelectedIcon} 132 | > 133 | {containerView} 134 | 135 | ); 136 | }; 137 | 138 | _renderTabNavigator = (route, navigator)=>{ 139 | var tabBarStyle = {}; 140 | var sceneStyle = {}; 141 | 142 | if (this.state.isHiddenTabBar) { 143 | tabBarStyle.height = 0; 144 | tabBarStyle.overflow = 'hidden'; 145 | sceneStyle.paddingBottom = 0; 146 | } 147 | 148 | // return ( 149 | // global.tabbar = tabbar} tabBarStyle={tabBarStyle} sceneStyle={sceneStyle}> 150 | // {this._renderTabItem('推荐', homeTabTag, ()=>this._tabItemIcon(false, homeSVGPaths), ()=>this._tabItemIcon(true, homeSVGPaths), this._renderNavigatorContent(homeTabTag, Home))} 151 | // {this._renderTabItem('图库', albumTabTag, ()=>this._tabItemIcon(false, albumSVGPaths), ()=>this._tabItemIcon(true, albumSVGPaths), this._renderNavigatorContent(albumTabTag, Album))} 152 | // {this._renderTabItem('商家', merchantTabTag, ()=>this._tabItemIcon(false, merchantSVGPaths), ()=>this._tabItemIcon(true, merchantSVGPaths), this._renderNavigatorContent(merchantTabTag, Merchant))} 153 | // 154 | // ); 155 | return ( 156 | global.tabbar = tabbar} tabBarStyle={tabBarStyle} sceneStyle={sceneStyle}> 157 | {this._renderTabItem('推荐', homeTabTag, ()=>this._tabItemIcon(false, homeSVGPaths), ()=>this._tabItemIcon(true, homeSVGPaths), )} 158 | {this._renderTabItem('图库', albumTabTag, ()=>this._tabItemIcon(false, albumSVGPaths), ()=>this._tabItemIcon(true, albumSVGPaths), )} 159 | {this._renderTabItem('商家', merchantTabTag, ()=>this._tabItemIcon(false, merchantSVGPaths), ()=>this._tabItemIcon(true, merchantSVGPaths), )} 160 | 161 | ); 162 | } 163 | 164 | _renderScene = (route, navigator)=> { 165 | console.log("routeId : "+route.routeId); 166 | const Comp = route.component; 167 | if (Comp) { 168 | return 169 | } 170 | switch (route.routeId) { 171 | case "TabNavigator": 172 | console.log("TabNavigator"); 173 | return (this._renderTabNavigator(route, navigator)); 174 | break; 175 | case homeTabTag: 176 | console.log("homeTabTag"); 177 | return (); 178 | break; 179 | case albumTabTag: 180 | console.log("albumTabTag"); 181 | return (); 182 | break; 183 | case "MerchantDetail": 184 | return (); 185 | break; 186 | default: 187 | return (this._renderTabNavigator(route, navigator)); 188 | } 189 | 190 | } 191 | 192 | render() { 193 | 194 | 195 | return ( 196 | // this._renderTabNavigator() 197 | { 201 | if (route.sceneConfig) { 202 | return route.sceneConfig; 203 | } 204 | return Navigator.SceneConfigs.PushFromRight; 205 | } 206 | } 207 | /> 208 | ); 209 | // return (); 210 | 211 | } 212 | } 213 | 214 | const styles = StyleSheet.create({ 215 | container:{ 216 | flex:1, 217 | }, 218 | selectedTitleStyle:{ 219 | color:'#ff5942', 220 | }, 221 | }); 222 | 223 | 224 | // function mapStateToProps(state) { 225 | // return { 226 | // home: state.home, 227 | // } 228 | // } 229 | // 230 | // function mapDispatchToProps(dispatch) { 231 | // return { 232 | // actions: bindActionCreators(Actions, dispatch) 233 | // } 234 | // } 235 | // 236 | // export default connect(mapStateToProps, mapDispatchToProps)(Marry) 237 | -------------------------------------------------------------------------------- /js/svg/FaceIcon.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react'; 2 | 3 | import Svg, { 4 | Circle, 5 | G, 6 | Path, 7 | Polygon, 8 | } from 'react-native-svg'; 9 | 10 | export default class FaceIcon extends Component { 11 | static propTypes = { 12 | faceType: PropTypes.number, 13 | }; 14 | static defaultProps = { 15 | faceType: 0, 16 | }; 17 | render() { 18 | 19 | switch (this.props.faceType) { 20 | case 0: 21 | return ( 22 | 23 | 24 | 27 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 40 | 41 | 42 | 43 | ); 44 | break; 45 | case 1: 46 | return ( 47 | 48 | 49 | 51 | 52 | 53 | 55 | 56 | 57 | 59 | 61 | 62 | 63 | 64 | 65 | ); 66 | break; 67 | 68 | case 2: 69 | return ( 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | ); 86 | break; 87 | case 3: 88 | return ( 89 | 90 | 91 | 94 | 95 | 97 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | ); 107 | break; 108 | case 4: 109 | return ( 110 | 112 | 113 | 116 | 117 | 118 | 119 | 120 | 123 | 124 | 125 | ); 126 | break; 127 | case 5: 128 | return ( 129 | 130 | 131 | 134 | 136 | 138 | 139 | 140 | ); 141 | break; 142 | case 6: 143 | return ( 144 | 145 | 146 | 149 | 151 | 153 | 155 | 157 | 159 | 160 | 161 | ); 162 | break; 163 | case 7: 164 | return ( 165 | 166 | 167 | 169 | 171 | 173 | 175 | 176 | 177 | ); 178 | break; 179 | case 8: 180 | return ( 181 | 182 | 183 | 186 | 187 | 189 | 191 | 193 | 195 | 196 | 197 | ); 198 | break; 199 | case 9: 200 | return ( 201 | 202 | 203 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 219 | 220 | 222 | 224 | 225 | 226 | 227 | ); 228 | break; 229 | case 10: 230 | return ( 231 | 232 | 235 | 240 | 241 | 242 | 243 | 244 | 246 | 247 | 248 | 249 | 250 | 251 | 253 | 254 | 255 | 256 | 257 | ); 258 | break; 259 | case 11: 260 | return ( 261 | 262 | 263 | 266 | 267 | 269 | 270 | 271 | 272 | 274 | 275 | 276 | 278 | 279 | 280 | 281 | 282 | ); 283 | break; 284 | default: 285 | return ( 286 | 287 | 288 | 291 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 304 | 305 | 306 | 307 | ); 308 | } 309 | 310 | 311 | } 312 | } 313 | 314 | // body{ 315 | // background:#2D2E3F; 316 | // } 317 | // .st0{ 318 | // fill=#DBA6F5;/*purple*/ 319 | // } 320 | // .st1{ 321 | // fill=#F7696D;/*red*/ 322 | // } 323 | // .st2{ 324 | // fill=#41C2ED;/*blue*/ 325 | // } 326 | // .st3{ 327 | // fill=#F7CE30;/*yellow*/ 328 | // } 329 | // .st4{ 330 | // fill=#FFFFFF;/*white*/ 331 | // } 332 | // svg{ 333 | // width:15%; 334 | // height:15%; 335 | // } 336 | --------------------------------------------------------------------------------