@@ -0,0 +1,10 @@ | |||
{ | |||
"presets": ["module:metro-react-native-babel-preset"], | |||
"plugins": [ | |||
["@babel/plugin-proposal-decorators", { "legacy": true }], | |||
["@babel/transform-runtime", { | |||
"helpers": true, | |||
"regenerator": false | |||
}] | |||
] | |||
} |
@@ -23,51 +23,22 @@ import { | |||
DebugInstructions, | |||
ReloadInstructions, | |||
} from 'react-native/Libraries/NewAppScreen'; | |||
import {TeaNavigator, TopView} from 'teaset'; | |||
import {Provider} from 'react-redux'; | |||
import MainPage from './src/views/MainPage'; | |||
import configureStore from './src/store/index'; | |||
const store = configureStore(); | |||
const App: () => React$Node = () => { | |||
return ( | |||
<> | |||
<StatusBar barStyle="dark-content" /> | |||
<SafeAreaView> | |||
<ScrollView | |||
contentInsetAdjustmentBehavior="automatic" | |||
style={styles.scrollView}> | |||
<Header /> | |||
{global.HermesInternal == null ? null : ( | |||
<View style={styles.engine}> | |||
<Text style={styles.footer}>Engine: Hermes</Text> | |||
</View> | |||
)} | |||
<View style={styles.body}> | |||
<View style={styles.sectionContainer}> | |||
<Text style={styles.sectionTitle}>Step One</Text> | |||
<Text style={styles.sectionDescription}> | |||
Edit <Text style={styles.highlight}>App.js</Text> to change this | |||
screen and then come back to see your edits. | |||
</Text> | |||
</View> | |||
<View style={styles.sectionContainer}> | |||
<Text style={styles.sectionTitle}>See Your Changes</Text> | |||
<Text style={styles.sectionDescription}> | |||
<ReloadInstructions /> | |||
</Text> | |||
</View> | |||
<View style={styles.sectionContainer}> | |||
<Text style={styles.sectionTitle}>Debug</Text> | |||
<Text style={styles.sectionDescription}> | |||
<DebugInstructions /> | |||
</Text> | |||
</View> | |||
<View style={styles.sectionContainer}> | |||
<Text style={styles.sectionTitle}>Learn More</Text> | |||
<Text style={styles.sectionDescription}> | |||
Read the docs to discover what to do next: | |||
</Text> | |||
</View> | |||
<LearnMoreLinks /> | |||
</View> | |||
</ScrollView> | |||
</SafeAreaView> | |||
<Provider store={store}> | |||
<TopView> | |||
<TeaNavigator rootView={ | |||
<MainPage /> | |||
}/> | |||
</TopView> | |||
</Provider> | |||
</> | |||
); | |||
}; | |||
@@ -296,6 +296,8 @@ PODS: | |||
- React-Core (= 0.63.3) | |||
- React-cxxreact (= 0.63.3) | |||
- React-jsi (= 0.63.3) | |||
- RNCAsyncStorage (1.13.2): | |||
- React | |||
- Yoga (1.14.0) | |||
- YogaKit (1.18.1): | |||
- Yoga (~> 1.14) | |||
@@ -347,6 +349,7 @@ DEPENDENCIES: | |||
- React-RCTText (from `../node_modules/react-native/Libraries/Text`) | |||
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) | |||
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) | |||
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" | |||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`) | |||
SPEC REPOS: | |||
@@ -415,6 +418,8 @@ EXTERNAL SOURCES: | |||
:path: "../node_modules/react-native/Libraries/Vibration" | |||
ReactCommon: | |||
:path: "../node_modules/react-native/ReactCommon" | |||
RNCAsyncStorage: | |||
:path: "../node_modules/@react-native-async-storage/async-storage" | |||
Yoga: | |||
:path: "../node_modules/react-native/ReactCommon/yoga" | |||
@@ -455,6 +460,7 @@ SPEC CHECKSUMS: | |||
React-RCTText: 65a6de06a7389098ce24340d1d3556015c38f746 | |||
React-RCTVibration: 8e9fb25724a0805107fc1acc9075e26f814df454 | |||
ReactCommon: 4167844018c9ed375cc01a843e9ee564399e53c3 | |||
RNCAsyncStorage: bc2f81cc1df90c267ce9ed30bb2dbc93b945a8ee | |||
Yoga: 7d13633d129fd179e01b8953d38d47be90db185a | |||
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a | |||
@@ -364,6 +364,17 @@ | |||
"@babel/helper-plugin-utils": "^7.10.4" | |||
} | |||
}, | |||
"@babel/plugin-proposal-decorators": { | |||
"version": "7.12.1", | |||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.12.1.tgz", | |||
"integrity": "sha512-knNIuusychgYN8fGJHONL0RbFxLGawhXOJNLBk75TniTsZZeA+wdkDuv6wp4lGwzQEKjZi6/WYtnb3udNPmQmQ==", | |||
"dev": true, | |||
"requires": { | |||
"@babel/helper-create-class-features-plugin": "^7.12.1", | |||
"@babel/helper-plugin-utils": "^7.10.4", | |||
"@babel/plugin-syntax-decorators": "^7.12.1" | |||
} | |||
}, | |||
"@babel/plugin-proposal-export-default-from": { | |||
"version": "7.12.1", | |||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.12.1.tgz", | |||
@@ -437,6 +448,15 @@ | |||
"@babel/helper-plugin-utils": "^7.10.4" | |||
} | |||
}, | |||
"@babel/plugin-syntax-decorators": { | |||
"version": "7.12.1", | |||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.12.1.tgz", | |||
"integrity": "sha512-ir9YW5daRrTYiy9UJ2TzdNIJEZu8KclVzDcfSt4iEmOtwQ4llPtWInNKJyKnVXp1vE4bbVd5S31M/im3mYMO1w==", | |||
"dev": true, | |||
"requires": { | |||
"@babel/helper-plugin-utils": "^7.10.4" | |||
} | |||
}, | |||
"@babel/plugin-syntax-dynamic-import": { | |||
"version": "7.8.3", | |||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", | |||
@@ -2160,6 +2180,14 @@ | |||
"chalk": "^3.0.0" | |||
} | |||
}, | |||
"@react-native-async-storage/async-storage": { | |||
"version": "1.13.2", | |||
"resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.13.2.tgz", | |||
"integrity": "sha512-isTDvUApRJPVWFxV15yrQSOGqarX7cIedq/y4N5yWSnotf68D9qvDEv1I7rCXhkBDi0u4OJt6GA9dksUT0D3wg==", | |||
"requires": { | |||
"deep-assign": "^3.0.0" | |||
} | |||
}, | |||
"@react-native-community/cli-debugger-ui": { | |||
"version": "4.13.1", | |||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-4.13.1.tgz", | |||
@@ -2781,6 +2809,14 @@ | |||
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", | |||
"dev": true | |||
}, | |||
"axios": { | |||
"version": "0.21.0", | |||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.0.tgz", | |||
"integrity": "sha512-fmkJBknJKoZwem3/IKSSLpkdNXZeBu5Q7GA/aRsr2btgrptmSCxi2oFjZHqGdK9DoTil9PIHlPIZw2EcRJXRvw==", | |||
"requires": { | |||
"follow-redirects": "^1.10.0" | |||
} | |||
}, | |||
"babel-eslint": { | |||
"version": "10.1.0", | |||
"resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", | |||
@@ -3407,6 +3443,45 @@ | |||
"parse-json": "^4.0.0" | |||
} | |||
}, | |||
"create-react-class": { | |||
"version": "15.6.0", | |||
"resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.0.tgz", | |||
"integrity": "sha1-q0SEl8JlZuHilBPogyB9V8/nvtQ=", | |||
"requires": { | |||
"fbjs": "^0.8.9", | |||
"loose-envify": "^1.3.1", | |||
"object-assign": "^4.1.1" | |||
}, | |||
"dependencies": { | |||
"core-js": { | |||
"version": "1.2.7", | |||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", | |||
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" | |||
}, | |||
"fbjs": { | |||
"version": "0.8.17", | |||
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", | |||
"integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", | |||
"requires": { | |||
"core-js": "^1.0.0", | |||
"isomorphic-fetch": "^2.1.1", | |||
"loose-envify": "^1.0.0", | |||
"object-assign": "^4.1.0", | |||
"promise": "^7.1.1", | |||
"setimmediate": "^1.0.5", | |||
"ua-parser-js": "^0.7.18" | |||
} | |||
}, | |||
"promise": { | |||
"version": "7.3.1", | |||
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", | |||
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", | |||
"requires": { | |||
"asap": "~2.0.3" | |||
} | |||
} | |||
} | |||
}, | |||
"cross-spawn": { | |||
"version": "6.0.5", | |||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", | |||
@@ -3499,6 +3574,14 @@ | |||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", | |||
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" | |||
}, | |||
"deep-assign": { | |||
"version": "3.0.0", | |||
"resolved": "https://registry.npmjs.org/deep-assign/-/deep-assign-3.0.0.tgz", | |||
"integrity": "sha512-YX2i9XjJ7h5q/aQ/IM9PEwEnDqETAIYbggmdDB3HLTlSgo1CxPsj6pvhPG68rq6SVE0+p+6Ywsm5fTYNrYtBWw==", | |||
"requires": { | |||
"is-obj": "^1.0.0" | |||
} | |||
}, | |||
"deep-is": { | |||
"version": "0.1.3", | |||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", | |||
@@ -4743,6 +4826,11 @@ | |||
"integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", | |||
"dev": true | |||
}, | |||
"follow-redirects": { | |||
"version": "1.13.0", | |||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", | |||
"integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==" | |||
}, | |||
"for-in": { | |||
"version": "1.0.2", | |||
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", | |||
@@ -4983,6 +5071,14 @@ | |||
"source-map": "^0.7.3" | |||
} | |||
}, | |||
"hoist-non-react-statics": { | |||
"version": "3.3.2", | |||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", | |||
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", | |||
"requires": { | |||
"react-is": "^16.7.0" | |||
} | |||
}, | |||
"hosted-git-info": { | |||
"version": "2.8.8", | |||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", | |||
@@ -5052,6 +5148,11 @@ | |||
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz", | |||
"integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA==" | |||
}, | |||
"immutable": { | |||
"version": "3.7.6", | |||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", | |||
"integrity": "sha1-E7TTyxK++hVIKib+Gy665kAHHks=" | |||
}, | |||
"import-fresh": { | |||
"version": "2.0.0", | |||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", | |||
@@ -5378,6 +5479,11 @@ | |||
} | |||
} | |||
}, | |||
"is-obj": { | |||
"version": "1.0.1", | |||
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", | |||
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" | |||
}, | |||
"is-plain-object": { | |||
"version": "2.0.4", | |||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", | |||
@@ -9955,6 +10061,60 @@ | |||
} | |||
} | |||
}, | |||
"react-native-legacy-components": { | |||
"version": "0.1.3", | |||
"resolved": "https://registry.npmjs.org/react-native-legacy-components/-/react-native-legacy-components-0.1.3.tgz", | |||
"integrity": "sha512-qiYtJl1xhLeWcHnh19L1MTUCKEOR7RPztuz/20XmI9/1Z4j1DeWHhUo4qZFzYpBPqBa6opFgV+u2Dp61bbRXtg==", | |||
"requires": { | |||
"create-react-class": "15.6.0", | |||
"fbjs": "~0.8.9", | |||
"immutable": "~3.7.6", | |||
"prop-types": "^15.5.10", | |||
"react-timer-mixin": "^0.13.2", | |||
"rebound": "^0.0.13" | |||
}, | |||
"dependencies": { | |||
"core-js": { | |||
"version": "1.2.7", | |||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", | |||
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" | |||
}, | |||
"fbjs": { | |||
"version": "0.8.17", | |||
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", | |||
"integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", | |||
"requires": { | |||
"core-js": "^1.0.0", | |||
"isomorphic-fetch": "^2.1.1", | |||
"loose-envify": "^1.0.0", | |||
"object-assign": "^4.1.0", | |||
"promise": "^7.1.1", | |||
"setimmediate": "^1.0.5", | |||
"ua-parser-js": "^0.7.18" | |||
} | |||
}, | |||
"promise": { | |||
"version": "7.3.1", | |||
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", | |||
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", | |||
"requires": { | |||
"asap": "~2.0.3" | |||
} | |||
} | |||
} | |||
}, | |||
"react-redux": { | |||
"version": "7.2.2", | |||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.2.tgz", | |||
"integrity": "sha512-8+CQ1EvIVFkYL/vu6Olo7JFLWop1qRUeb46sGtIMDCSpgwPQq8fPLpirIB0iTqFe9XYEFPHssdX8/UwN6pAkEA==", | |||
"requires": { | |||
"@babel/runtime": "^7.12.1", | |||
"hoist-non-react-statics": "^3.3.2", | |||
"loose-envify": "^1.4.0", | |||
"prop-types": "^15.7.2", | |||
"react-is": "^16.13.1" | |||
} | |||
}, | |||
"react-refresh": { | |||
"version": "0.4.3", | |||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz", | |||
@@ -9972,6 +10132,11 @@ | |||
"scheduler": "^0.19.1" | |||
} | |||
}, | |||
"react-timer-mixin": { | |||
"version": "0.13.4", | |||
"resolved": "https://registry.npmjs.org/react-timer-mixin/-/react-timer-mixin-0.13.4.tgz", | |||
"integrity": "sha512-4+ow23tp/Tv7hBM5Az5/Be/eKKF7DIvJ09voz5LyHGQaqqz9WV8YMs31eFvcYQs7d451LSg7kDJV70XYN/Ug/Q==" | |||
}, | |||
"read-pkg": { | |||
"version": "5.2.0", | |||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", | |||
@@ -10043,6 +10208,32 @@ | |||
"integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", | |||
"dev": true | |||
}, | |||
"rebound": { | |||
"version": "0.0.13", | |||
"resolved": "https://registry.npmjs.org/rebound/-/rebound-0.0.13.tgz", | |||
"integrity": "sha1-SiJSVMr32nVnl7GcWBe/enlB+sE=" | |||
}, | |||
"redux": { | |||
"version": "4.0.5", | |||
"resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz", | |||
"integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==", | |||
"requires": { | |||
"loose-envify": "^1.4.0", | |||
"symbol-observable": "^1.2.0" | |||
}, | |||
"dependencies": { | |||
"symbol-observable": { | |||
"version": "1.2.0", | |||
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", | |||
"integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" | |||
} | |||
} | |||
}, | |||
"redux-thunk": { | |||
"version": "2.3.0", | |||
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", | |||
"integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==" | |||
}, | |||
"regenerate": { | |||
"version": "1.4.2", | |||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", | |||
@@ -11079,6 +11270,15 @@ | |||
} | |||
} | |||
}, | |||
"teaset": { | |||
"version": "0.7.5", | |||
"resolved": "https://registry.npmjs.org/teaset/-/teaset-0.7.5.tgz", | |||
"integrity": "sha512-wWCEvJtNmFm1Pcpcjs7+jP7C9sAGx1va1mBT2dUmjkG8IjL/zA/k//Gvd4HyNwNpg5F3Jexwe8K9S1dK42KIgA==", | |||
"requires": { | |||
"prop-types": "^15.7.2", | |||
"react-native-legacy-components": "^0.1.3" | |||
} | |||
}, | |||
"temp": { | |||
"version": "0.8.3", | |||
"resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", | |||
@@ -10,11 +10,18 @@ | |||
"lint": "eslint ." | |||
}, | |||
"dependencies": { | |||
"@react-native-async-storage/async-storage": "^1.13.2", | |||
"axios": "^0.21.0", | |||
"react": "16.13.1", | |||
"react-native": "0.63.3" | |||
"react-native": "0.63.3", | |||
"react-redux": "^7.2.2", | |||
"redux": "^4.0.5", | |||
"redux-thunk": "^2.3.0", | |||
"teaset": "^0.7.5" | |||
}, | |||
"devDependencies": { | |||
"@babel/core": "7.12.7", | |||
"@babel/plugin-proposal-decorators": "^7.12.1", | |||
"@babel/runtime": "7.12.5", | |||
"@react-native-community/eslint-config": "1.1.0", | |||
"babel-jest": "25.5.1", | |||
@@ -0,0 +1,10 @@ | |||
import request from '../utils/request'; | |||
// 获取首页列表数据 | |||
export function getHomeList(params = {}){ | |||
return request({ | |||
url: '/v1/homepage', | |||
method: 'GET', | |||
params: {...params} | |||
}); | |||
} |
@@ -0,0 +1,120 @@ | |||
// BasePage.js | |||
'use strict'; | |||
import React, {Component} from 'react'; | |||
import PropTypes from 'prop-types'; | |||
import ReactNative, {Platform, View, ViewPropTypes} from 'react-native'; | |||
import {Theme, KeyboardSpace, TeaNavigator, Toast} from "teaset"; | |||
export default class CustomBasePage extends Component { | |||
static propTypes = { | |||
...ViewPropTypes, | |||
scene: PropTypes.object, //转场效果 | |||
autoKeyboardInsets: PropTypes.bool, //自动插入键盘占用空间 | |||
keyboardTopInsets: PropTypes.number, //插入键盘占用空间顶部偏移,用于底部有固定占用空间(如TabNavigator)的页面 | |||
}; | |||
static defaultProps = { | |||
...View.defaultProps, | |||
scene: TeaNavigator.SceneConfigs.Replace, | |||
autoKeyboardInsets: Platform.OS === 'ios', | |||
keyboardTopInsets: 0, | |||
}; | |||
static contextTypes = { | |||
navigator: PropTypes.func, | |||
}; | |||
constructor(props) { | |||
super(props); | |||
this.didMount = false; //代替被废弃的isMounted | |||
this.isFocused = false; //this.state.isFocused move to this.isFocused | |||
this.state = { | |||
}; | |||
} | |||
UNSAFE_componentWillMount() { | |||
if (!this.backListener && Platform.OS === 'android') { | |||
let BackHandler = ReactNative.BackHandler ? ReactNative.BackHandler : ReactNative.BackAndroid; | |||
this.backListener = BackHandler.addEventListener('hardwareBackPress', () => this.onHardwareBackPress()); | |||
} | |||
} | |||
componentDidMount() { | |||
this.didMount = true; | |||
} | |||
componentWillUnmount() { | |||
if (this.backListener) { | |||
this.backListener.remove(); | |||
this.backListener = null; | |||
} | |||
this.didMount = false; | |||
} | |||
get navigator() { | |||
if (!this.context.navigator) { | |||
console.error('The root component is NOT TeaNavigator, then you can not use BasePage.navigator.'); | |||
return null; | |||
} | |||
return this.context.navigator(); | |||
} | |||
//Call after the scene transition by Navigator.onDidFocus | |||
onDidFocus() { | |||
this.isFocused = true; | |||
} | |||
//Call before the scene transition by Navigator.onWillFocus | |||
onWillFocus() { | |||
} | |||
//Android hardware back key handler, default is pop to prev page | |||
onHardwareBackPress() { | |||
if (!this.context.navigator) return false; | |||
let navigator = this.context.navigator(); | |||
if (!navigator) return false; | |||
if (navigator.getCurrentRoutes().length > 1) { | |||
navigator.pop(); | |||
return true; | |||
} | |||
if (navigator.getCurrentRoutes().length === 1) { | |||
if (this.lastBackPressed && this.lastBackPressed + 2000 >= Date.now()) { | |||
//最近2秒内按过back键,可以退出应用。 | |||
ReactNative.BackHandler.exitApp(); | |||
return false; | |||
} | |||
this.lastBackPressed = Date.now(); | |||
Toast.message('再按一次退出应用'); | |||
return true; | |||
} | |||
return false; | |||
} | |||
buildStyle() { | |||
let {style} = this.props; | |||
style = [{ | |||
flex: 1, | |||
backgroundColor: Theme.pageColor, | |||
}].concat(style); | |||
return style; | |||
} | |||
renderPage() { | |||
return null; | |||
} | |||
render() { | |||
let {style, children, scene, autoKeyboardInsets, keyboardTopInsets, ...others} = this.props; | |||
return ( | |||
<View style={this.buildStyle()} {...others}> | |||
{this.renderPage()} | |||
{autoKeyboardInsets ? <KeyboardSpace topInsets={keyboardTopInsets} /> : null} | |||
</View> | |||
); | |||
} | |||
} |
@@ -0,0 +1,117 @@ | |||
'use strict'; | |||
import React, {Component} from 'react'; | |||
import PropTypes from 'prop-types'; | |||
import {Platform, View, Dimensions, Text} from 'react-native'; | |||
import {BasePage, KeyboardSpace, NavigationBar, Theme, TeaNavigator} from "teaset"; | |||
import CustomBasePage from "./CustomBasePage"; | |||
import { hairWidth } from '../utils' | |||
import { Color } from 'chalk'; | |||
export default class CustomPage extends CustomBasePage { | |||
static propTypes = { | |||
...BasePage.propTypes, | |||
title: PropTypes.string, | |||
backgroundColor: PropTypes.string, | |||
tintColor: PropTypes.string, | |||
titleStyle: Text.propTypes.style, | |||
showBackButton: PropTypes.bool, | |||
navigationBarInsets: PropTypes.bool, | |||
}; | |||
static defaultProps = { | |||
...BasePage.defaultProps, | |||
scene: TeaNavigator.SceneConfigs.PushFromRight, | |||
title: null, | |||
backgroundColor: 'transparent', | |||
tintColor: '#FFFFFF', | |||
titleStyle: null, | |||
showBackButton: false, | |||
navigationBarInsets: true, | |||
}; | |||
constructor(props) { | |||
super(props); | |||
this.screenWidth = Dimensions.get('window').width; | |||
} | |||
setTitle(title){ | |||
this.setState({title}); | |||
} | |||
onLayout(e) { | |||
let {width} = Dimensions.get('window'); | |||
if (width != this.screenWidth) { | |||
this.screenWidth = width; | |||
this.forceUpdate(); | |||
} | |||
this.props.onLayout && this.props.onLayout(e); | |||
} | |||
renderNavigationTitle() { | |||
return this.state.title || this.props.title; | |||
} | |||
renderNavigationLeftView() { | |||
if (!this.props.showBackButton) return null; | |||
return ( | |||
<NavigationBar.BackButton | |||
title={this.props.hasOwnProperty('backButtonTitle') ? this.props.backButtonTitle : Theme.backButtonTitle} | |||
onPress={() => { | |||
this.onBackPress ? this.onBackPress() : this.navigator.pop() | |||
}} | |||
/> | |||
); | |||
} | |||
renderNavigationRightView() { | |||
return null; | |||
} | |||
renderNavigationBar() { | |||
return ( | |||
<NavigationBar | |||
tintColor={this.props.tintColor} | |||
backgroundColor={this.props.backgroundColor} | |||
titleStyle={this.props.titleStyle} | |||
title={this.renderNavigationTitle()} | |||
leftView={this.renderNavigationLeftView()} | |||
rightView={this.renderNavigationRightView()} | |||
/> | |||
); | |||
} | |||
renderPage() { | |||
return null; | |||
} | |||
render() { | |||
let {style, children, scene, autoKeyboardInsets, keyboardTopInsets, title, showBackButton, navigationBarInsets, ...others} = this.props; | |||
let {left: paddingLeft, right: paddingRight} = Theme.screenInset; | |||
let pageContainerStyle = [{ | |||
flex: 1, | |||
paddingLeft, | |||
paddingRight, | |||
marginTop: navigationBarInsets ? (Theme.navBarContentHeight + Theme.statusBarHeight) : 0, | |||
}]; | |||
return ( | |||
<View style={this.buildStyle()} onLayout={e => this.onLayout(e)} {...others}> | |||
<View style={{flex: 1}}> | |||
<View style={pageContainerStyle}> | |||
{this.renderPage()} | |||
</View> | |||
{this.renderNavigationBar()} | |||
</View> | |||
{autoKeyboardInsets ? <KeyboardSpace topInsets={keyboardTopInsets}/> : null} | |||
</View> | |||
); | |||
} | |||
} | |||
@@ -0,0 +1,76 @@ | |||
import {Dimensions, Platform, StatusBar} from "react-native"; | |||
const X_WIDTH = 375; | |||
const X_HEIGHT = 812; | |||
const XSMAX_WIDTH = 414; | |||
const XSMAX_HEIGHT = 896; | |||
const {width: D_WIDTH, height: D_HEIGHT} = Dimensions.get('window'); | |||
const isIPhoneX = (() => { | |||
if (Platform.OS === 'web') return false; | |||
return ( | |||
Platform.OS === 'ios' && | |||
((D_HEIGHT === X_HEIGHT && D_WIDTH === X_WIDTH) || | |||
(D_HEIGHT === X_WIDTH && D_WIDTH === X_HEIGHT)) || | |||
((D_HEIGHT === XSMAX_HEIGHT && D_WIDTH === XSMAX_WIDTH) || | |||
(D_HEIGHT === XSMAX_WIDTH && D_WIDTH === XSMAX_HEIGHT)) | |||
); | |||
})(); | |||
const isLandscape = (() => { | |||
return Dimensions.get('window').width > Dimensions.get('window').height; | |||
})(); | |||
export function getStatusBarHeight() { | |||
if (Platform.OS === 'ios') { | |||
if (isIPhoneX) return isLandscape ? 0 : 44; | |||
} else if (Platform.OS === 'android') { | |||
if (Platform.Version > 20) return StatusBar.currentHeight; | |||
return 0; | |||
} | |||
return isLandscape ? 0 : 20; | |||
} | |||
export function getBottomOffset() { | |||
if (Platform.OS === 'ios') { | |||
if (isIPhoneX) return isLandscape ? 24 : 34; | |||
} else if (Platform.OS === 'android') { | |||
if (Platform.Version > 20) return 0; | |||
return 0; | |||
} | |||
return isLandscape ? 0 : 20; | |||
} | |||
export function getScreenInset() { | |||
let statusBarHeight = getStatusBarHeight() | |||
return ({ | |||
left: isLandscape && isIPhoneX ? 44 : 0, | |||
right: isLandscape && isIPhoneX ? 44 : 0, | |||
top: statusBarHeight, | |||
bottom: isIPhoneX ? (isLandscape ? 24 : 34) : 0, | |||
}); | |||
} | |||
export function formatNumber(data) { | |||
if (data != null) { | |||
return data.toFixed(2); | |||
} else { | |||
return null; | |||
} | |||
} | |||
export function desensitizeMobile(mobile) { | |||
if (mobile && mobile.length >= 11) { | |||
return mobile.substr(0, 3) + " **** " + mobile.substr(mobile.length - 4, 4); | |||
} | |||
return mobile; | |||
} | |||
export function desensitizeBankcardNo(bankcardNo) { | |||
if (bankcardNo && bankcardNo.length >= 10) { | |||
return bankcardNo.substr(0, 4) + " **** **** " + bankcardNo.substr(bankcardNo.length - 4, 4); | |||
} | |||
return bankcardNo; | |||
} |
@@ -0,0 +1,20 @@ | |||
import {applyMiddleware, createStore} from 'redux'; | |||
import thunkMiddleware from 'redux-thunk'; | |||
import rootReducer from './reducers/index' | |||
export function createReducer(initialState, handlers) { | |||
return function reducer(state = initialState, action) { | |||
if (handlers.hasOwnProperty(action.type)) { | |||
return handlers[action.type](state, action); | |||
} else { | |||
return state; | |||
} | |||
} | |||
} | |||
const createStoreWithMW = applyMiddleware(thunkMiddleware)(createStore); | |||
export default function configureStore(initialState) { | |||
const store = createStoreWithMW(rootReducer, initialState); | |||
return store; | |||
} |
@@ -0,0 +1,12 @@ | |||
const initialState = { | |||
deviceType: 1, | |||
deviceToken: '' | |||
}; | |||
export default function login(state = initialState, action) { | |||
return { | |||
...state, | |||
deviceType: action.deviceType, | |||
deviceToken: action.deviceToken | |||
} | |||
} |
@@ -0,0 +1,12 @@ | |||
const initialState = { | |||
token: '', | |||
member: {} | |||
}; | |||
export default function login(state = initialState, action) { | |||
return { | |||
...state, | |||
token: action.token, | |||
member: action.member | |||
} | |||
} |
@@ -0,0 +1,10 @@ | |||
import {combineReducers} from "redux"; | |||
import login from "./LoginReducer"; | |||
import device from "./DeviceReducer"; | |||
const rootReducer = combineReducers({ | |||
login: login, | |||
device: device | |||
}); | |||
export default rootReducer; |
@@ -0,0 +1,49 @@ | |||
import React from 'react'; | |||
import {ActivityIndicator, DeviceEventEmitter} from "react-native"; | |||
import {Theme, Toast} from "teaset"; | |||
export default class CommonUtil { | |||
static toast = null | |||
static formatAmount(amount) { | |||
return (amount / 100).toFixed(2) + ''; | |||
} | |||
static isMobile(str) { | |||
let reg = /^[1][0-9]{10}$/; | |||
return reg.test(str); | |||
} | |||
static isCardNo(card) { | |||
let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/; | |||
return reg.test(card); | |||
} | |||
static trim(str) { | |||
if (!str) { | |||
return ''; | |||
} | |||
return str.replace(/^(\s*)|(\s*)$/g, ''); | |||
} | |||
static showLoading(str) { | |||
CommonUtil.toast = Toast.show({ | |||
text: str, | |||
icon: <ActivityIndicator size='large' color={Theme.toastIconTintColor}/>, | |||
position: 'center', | |||
duration: 60000 | |||
}); | |||
return CommonUtil.toast | |||
} | |||
static hideLoading() { | |||
if (CommonUtil.toast) { | |||
Toast.hide(CommonUtil.toast); | |||
} | |||
} | |||
static logOut(){ | |||
DeviceEventEmitter.emit('LOG_OUT'); | |||
} | |||
} |
@@ -0,0 +1,30 @@ | |||
/* | |||
* @Author: Hinjin | |||
* @Date: 2020-03-14 00:10:21 | |||
* @LastEditors: Hinjin | |||
* @LastEditTime: 2020-08-31 18:40:48 | |||
* @FilePath: src/utils/Constants.js | |||
*/ | |||
export default class Constants { | |||
static VERSION = '1.0.1'; | |||
static HOST = '101.133.164.241:8081'; | |||
static BASE_URL = 'http://101.133.164.241:8081/'; | |||
static KEY_TOEKN = 'Authorization'; | |||
static KEY_USER = 'userInfo'; | |||
static KEY_USER_NAME = 'userName'; | |||
static KEY_PASSWORD = 'password'; | |||
static KEY_REMEBER_ME = 'rememberMe'; | |||
static THEME_COLOR = '#12AA9C'; | |||
static GET_BASE_URL = (path = '') => { | |||
return `http://${window.host || Constants.HOST}/tms-service/api${path}`; | |||
} | |||
} |
@@ -0,0 +1,38 @@ | |||
import AsyncStorage from '@react-native-async-storage/async-storage'; | |||
export default class StorageUtil { | |||
static saveJson = async (key, value) => { | |||
await this.saveString(key, JSON.stringify(value)); | |||
} | |||
/** | |||
* 获取一个Json对象 | |||
* @param key | |||
*/ | |||
static getJson = async (key, callback) => { | |||
const res = await this.getString(key); | |||
const result = res ? JSON.parse(res) : res; | |||
callback && callback(result); | |||
return result; | |||
} | |||
static saveString = async (key, value) => { | |||
if (key != null && value != null) { | |||
await AsyncStorage.setItem(key, value) | |||
} | |||
return false | |||
} | |||
static getString = async (key, callback) => { | |||
const result = await AsyncStorage.getItem(key) | |||
if (callback) { | |||
callback && callback(result) | |||
} | |||
return result | |||
} | |||
static remove = async(key) => { | |||
return await AsyncStorage.removeItem(key).then(() => {}); | |||
} | |||
} |
@@ -0,0 +1,106 @@ | |||
import {Dimensions, Platform, StatusBar, PixelRatio} from "react-native"; | |||
import { Toast } from "teaset"; | |||
const X_WIDTH = 375; | |||
const X_HEIGHT = 812; | |||
const XSMAX_WIDTH = 414; | |||
const XSMAX_HEIGHT = 896; | |||
const {width: D_WIDTH, height: D_HEIGHT} = Dimensions.get('window'); | |||
const isIPhoneX = (() => { | |||
if (Platform.OS === 'web') return false; | |||
return ( | |||
Platform.OS === 'ios' && | |||
((D_HEIGHT === X_HEIGHT && D_WIDTH === X_WIDTH) || | |||
(D_HEIGHT === X_WIDTH && D_WIDTH === X_HEIGHT)) || | |||
((D_HEIGHT === XSMAX_HEIGHT && D_WIDTH === XSMAX_WIDTH) || | |||
(D_HEIGHT === XSMAX_WIDTH && D_WIDTH === XSMAX_HEIGHT)) | |||
); | |||
})(); | |||
const isLandscape = (() => { | |||
return Dimensions.get('window').width > Dimensions.get('window').height; | |||
})(); | |||
export const hairWidth = 1 / PixelRatio.get(); | |||
export function getStatusBarHeight() { | |||
if (Platform.OS === 'ios') { | |||
if (isIPhoneX) return isLandscape ? 0 : 44; | |||
} else if (Platform.OS === 'android') { | |||
if (Platform.Version > 20) return StatusBar.currentHeight; | |||
return 0; | |||
} | |||
return isLandscape ? 0 : 20; | |||
} | |||
export function getBottomOffset() { | |||
if (Platform.OS === 'ios') { | |||
if (isIPhoneX) return isLandscape ? 24 : 34; | |||
} else if (Platform.OS === 'android') { | |||
if (Platform.Version > 20) return 0; | |||
return 0; | |||
} | |||
return isLandscape ? 0 : 20; | |||
} | |||
export function getScreenInset() { | |||
let statusBarHeight = getStatusBarHeight() | |||
return ({ | |||
left: isLandscape && isIPhoneX ? 44 : 0, | |||
right: isLandscape && isIPhoneX ? 44 : 0, | |||
top: statusBarHeight, | |||
bottom: isIPhoneX ? (isLandscape ? 24 : 34) : 0, | |||
}); | |||
} | |||
export function formatNumber(data) { | |||
if (data != null) { | |||
return data.toFixed(2); | |||
} else { | |||
return null; | |||
} | |||
} | |||
export function desensitizeMobile(mobile) { | |||
if (mobile && mobile.length >= 11) { | |||
return mobile.substr(0, 3) + " **** " + mobile.substr(mobile.length - 4, 4); | |||
} | |||
return mobile; | |||
} | |||
export function desensitizeBankcardNo(bankcardNo) { | |||
if (bankcardNo && bankcardNo.length >= 10) { | |||
return bankcardNo.substr(0, 4) + " **** **** " + bankcardNo.substr(bankcardNo.length - 4, 4); | |||
} | |||
return bankcardNo; | |||
} | |||
/** | |||
* 非空校验 | |||
* @param {*} checkArr | |||
* @param {*} callback | |||
*/ | |||
export function paramsCheck(checkArr, callback) { | |||
let isValid = true; | |||
for (let i = 0; i < checkArr.length; i++) { | |||
// 若字段为空 | |||
if (checkArr[i].param) { | |||
isValid = false; | |||
Toast.fail(checkArr[i].tip); | |||
break; | |||
} | |||
} | |||
isValid && callback && callback(); | |||
} | |||
/** | |||
* 判断是否是数字 | |||
* @param {*} value | |||
*/ | |||
export function isNumber(value) { | |||
return typeof value === 'number' && !isNaN(value); | |||
} |
@@ -0,0 +1,67 @@ | |||
/* | |||
* @Author: Hinjin | |||
* @Date: 2020-03-15 19:48:49 | |||
* @LastEditors: Hinjin | |||
* @LastEditTime: 2020-09-01 22:56:26 | |||
* @FilePath: src/utils/request.js | |||
*/ | |||
import Constants from "./Constants"; | |||
import axios from 'axios'; | |||
import { Platform, AsyncStorage } from "react-native"; | |||
import StorageUtil from "./StorageUtil"; | |||
import CommonUtil from "./CommonUtil"; | |||
axios.defaults.baseURL = Constants.GET_BASE_URL(); | |||
axios.defaults.headers.post['Content-Type'] = 'application/json'; | |||
axios.defaults.headers.common['source'] = Platform.OS === "ios" ? 'app-ios' : 'app-android'; | |||
let isGetHost = false; | |||
const request = async ({ url, method = 'GET', params, data, headers }) => { | |||
const token = await StorageUtil.getString(Constants.KEY_TOEKN); | |||
if (!window.host && !isGetHost) { | |||
window.host = await StorageUtil.getString('host'); | |||
axios.defaults.baseURL = Constants.GET_BASE_URL(); | |||
isGetHost = true; | |||
} | |||
axios.defaults.headers.common['Authorization'] = token; | |||
if (!!headers && headers['Content-Type']) { | |||
axios.defaults.headers.post['Content-Type'] = headers['Content-Type']; | |||
}; | |||
const _headers = { | |||
...headers, | |||
Authorization: token | |||
} | |||
return axios({ | |||
method, | |||
url, | |||
params, | |||
data, | |||
headers: _headers, | |||
// headers: { | |||
// // 'Content-Type': 'multipart/form-data;', | |||
// Authorization: token | |||
// } | |||
}); | |||
} | |||
// 响应拦截器 | |||
axios.interceptors.response.use(res => { | |||
const code = res.data.code; | |||
// 登录失效 | |||
if (code === 99998) { | |||
CommonUtil.logOut(); | |||
return res.data.data; | |||
} else if (code !== 0) { | |||
return Promise.reject(res.data.msg) | |||
} else { | |||
return res.data.data; | |||
} | |||
}, | |||
error => { | |||
console.log('err' + error) | |||
return Promise.reject(error) | |||
} | |||
) | |||
export default request; |
@@ -0,0 +1,54 @@ | |||
import {BasePage, Carousel, Label, Overlay, Toast, Button} from "teaset"; | |||
import React from "react"; | |||
import { | |||
ActivityIndicator, | |||
Dimensions, | |||
FlatList, | |||
Image, PermissionsAndroid, Platform, | |||
ScrollView, | |||
AsyncStorage, | |||
StyleSheet, | |||
TouchableOpacity, | |||
TouchableWithoutFeedback, | |||
View, | |||
Text, | |||
RefreshControl, | |||
Animated, Easing, DeviceEventEmitter | |||
} from "react-native"; | |||
import {connect} from "react-redux"; | |||
import CustomPage from "../common/CustomPage"; | |||
import { getHomeList } from '../apis/home'; | |||
@connect( | |||
state => ({ | |||
}), dispatch => ({ | |||
}) | |||
) | |||
export default class HomePage extends CustomPage { | |||
static defaultProps = { | |||
...BasePage.defaultProps, | |||
backgroundColor: 'transparent', | |||
titleStyle: {color: '#000', fontWeight: 'bold', fontSize: 18}, | |||
title: '会员中心', | |||
}; | |||
async componentDidMount() { | |||
this.getData(); | |||
} | |||
async getData(){ | |||
try{ | |||
const res = await getHomeList({page: 1, page_size: 20}); | |||
console.log({res}); | |||
} catch(e){ | |||
console.log({e}); | |||
} | |||
} | |||
renderPage(){ | |||
return <View style={{flex: 1}}> | |||
</View> | |||
} | |||
} |
@@ -0,0 +1,130 @@ | |||
'use strict'; | |||
import React from "react"; | |||
import { | |||
Alert, | |||
Animated, | |||
DeviceEventEmitter, | |||
Dimensions, | |||
Easing, | |||
Image, | |||
NetInfo, | |||
Platform, | |||
TouchableOpacity, | |||
TouchableWithoutFeedback, | |||
View, | |||
Linking, NativeModules, | |||
} from "react-native"; | |||
import {connect} from "react-redux"; | |||
import {BasePage, Label, Overlay, TabView, TeaNavigator, Toast} from "teaset"; | |||
import CustomBasePage from "../common/CustomBasePage"; | |||
import HomePage from "./HomePage"; | |||
@connect( | |||
state => ({ | |||
loginState: state.login, | |||
}), dispatch => ({ | |||
}) | |||
) | |||
export default class MainPage extends CustomBasePage { | |||
static defaultProps = { | |||
...BasePage.defaultProps, | |||
scene: TeaNavigator.SceneConfigs.PushFromRight, | |||
}; | |||
constructor(props) { | |||
super(props); | |||
} | |||
goLogin() { | |||
// this.navigator.push({ | |||
// view: <LoginPage /> | |||
// }) | |||
} | |||
renderPage() { | |||
let {type, custom, activeIndex, goodsCount} = this.state; | |||
let {loginState} = this.props | |||
let customBarStyle = Platform.OS === 'android' ? null : { | |||
borderTopWidth: 0, | |||
shadowColor: '#ccc', | |||
shadowOffset: {height: -1}, | |||
shadowOpacity: 0.4, | |||
shadowRadius: 0.5, | |||
}; | |||
return <View style={{flex: 1, position: 'relative'}}> | |||
<TabView style={{flex: 1}} barStyle={custom ? customBarStyle : null} type={type} activeIndex={activeIndex}> | |||
<TabView.Sheet | |||
title='首页' | |||
icon={require('../icons/home.png')} | |||
activeIcon={require('../icons/home_active.png')} | |||
onPress={() => { | |||
this.setState({activeIndex: 0}) | |||
}} | |||
> | |||
<HomePage | |||
type={type} | |||
custom={custom} | |||
onChangeType={type => this.setState({type})} | |||
onChangeCustom={custom => this.setState({custom})} | |||
/> | |||
</TabView.Sheet> | |||
<TabView.Sheet | |||
title='分类'category | |||
icon={require('../icons/home.png')} | |||
activeIcon={require('../icons/home_active.png')} | |||
onPress={() => { | |||
this.setState({activeIndex: 1}) | |||
}} | |||
> | |||
<HomePage | |||
type={type} | |||
custom={custom} | |||
onChangeType={type => this.setState({type})} | |||
onChangeCustom={custom => this.setState({custom})} | |||
/> | |||
</TabView.Sheet> | |||
<TabView.Sheet | |||
title='会员中心' | |||
icon={require('../icons/home.png')} | |||
activeIcon={require('../icons/home_active.png')} | |||
onPress={() => { | |||
if (!loginState.token) { | |||
this.goLogin() | |||
} else { | |||
this.setState({activeIndex: 2}) | |||
} | |||
}} | |||
> | |||
<HomePage | |||
type={type} | |||
custom={custom} | |||
onChangeType={type => this.setState({type})} | |||
onChangeCustom={custom => this.setsState({custom})} | |||
/> | |||
</TabView.Sheet> | |||
<TabView.Sheet | |||
title='我的' | |||
icon={require('../icons/home.png')} | |||
activeIcon={require('../icons/home_active.png')} | |||
onPress={() => { | |||
if (!loginState.token) { | |||
this.goLogin() | |||
} else { | |||
this.setState({activeIndex: 4}) | |||
} | |||
}} | |||
// badge={100} | |||
> | |||
<HomePage | |||
type={type} | |||
custom={custom} | |||
onChangeType={type => this.setState({type})} | |||
onChangeCustom={custom => this.setState({custom})} | |||
/> | |||
</TabView.Sheet> | |||
</TabView> | |||
</View>; | |||
} | |||
} |