├── .babelrc ├── .buckconfig ├── .flowconfig ├── .gitattributes ├── .gitignore ├── .watchmanconfig ├── README.md ├── __tests__ ├── index.android.js └── index.ios.js ├── android ├── app │ ├── BUCK │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ ├── com │ │ │ └── gcore │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ └── wxapi │ │ │ └── WXEntryActivity.java │ │ └── res │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ └── values │ │ ├── strings.xml │ │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── keystores │ ├── BUCK │ └── debug.keystore.properties └── settings.gradle ├── app.json ├── app ├── Lib │ ├── Carousel.js │ └── drawer │ │ ├── Drawer.js │ │ ├── tweenFunctions.js │ │ └── tweener.js ├── actions │ ├── application.js │ ├── article.js │ ├── categories.js │ ├── comment.js │ ├── download.js │ ├── home.js │ ├── myMark.js │ ├── news.js │ ├── pageInfo.js │ ├── play.js │ ├── radio.js │ ├── subscript.js │ ├── timeLine.js │ └── video.js ├── channel │ ├── DownloadManager.js │ ├── MyStorage.js │ ├── NetTool.js │ ├── address.js │ ├── index.js │ └── producer.js ├── common │ └── constants.js ├── components │ ├── airticle │ │ ├── Article.js │ │ ├── ArticleDetail.js │ │ └── Original.js │ ├── category │ │ ├── Category.js │ │ ├── CategoryCell.js │ │ └── CategoryDetail.js │ ├── custom │ │ └── SegmentedControl.js │ ├── home │ │ ├── Home.js │ │ ├── HomeBannar.js │ │ └── NewsScrooll.js │ ├── news │ │ ├── News.js │ │ └── NewsCell.js │ ├── other │ │ ├── Blank.js │ │ ├── Comment.js │ │ ├── CommentCell.js │ │ ├── DateHandel.js │ │ ├── DownloadList.js │ │ ├── Loading.js │ │ ├── MusicTool.js │ │ ├── Rename.js │ │ ├── Reply.js │ │ ├── Signin.js │ │ ├── TLView.js │ │ ├── custom │ │ │ └── MyIcon.js │ │ ├── me │ │ │ ├── Me.js │ │ │ ├── MyMark.js │ │ │ └── Subscript.js │ │ └── timeLine │ │ │ ├── AudioPlayer.js │ │ │ ├── TimeLine.js │ │ │ ├── TimeLineList.js │ │ │ └── TimeLinePanel.js │ ├── radio │ │ └── Radio.js │ └── video │ │ └── Video.js ├── containers │ ├── BanarNavigationBar.js │ ├── CommentNavigationBar.js │ ├── CommonNavigationBar.js │ ├── ControllerTabBar.js │ ├── MenuContainer.js │ ├── TabBar.js │ ├── TabBarView.js │ ├── ToolNavigationBar.js │ └── app.js ├── reducers │ ├── application.js │ ├── article.js │ ├── bannar.js │ ├── categories.js │ ├── comment.js │ ├── download.js │ ├── home.js │ ├── index.js │ ├── myMark.js │ ├── news.js │ ├── pageInfo.js │ ├── play.js │ ├── radio.js │ ├── subscript.js │ ├── timeLine.js │ └── video.js ├── resource │ ├── GGG.jpg │ ├── arrow-left~iphone.png │ ├── arrow-left~iphone@2x.png │ ├── default-avatar~iphone.png │ ├── default-avatar~iphone@2x.png │ ├── ic_tab_homepage.png │ ├── ic_tab_homepage_select.png │ ├── ic_tab_my.png │ ├── ic_tab_my_select.png │ ├── ic_tab_search.png │ ├── ic_tab_search_select.png │ ├── ic_tab_shop.png │ ├── ic_tab_shop_select.png │ ├── icon-category~iphone.png │ ├── icon-category~iphone@2x.png │ ├── icon-close-down.png │ ├── icon-close-down@2x.png │ ├── icon-comment-wo~iphone.png │ ├── icon-comment-wo~iphone@2x.png │ ├── icon-comment-w~iphone.png │ ├── icon-comment-w~iphone@2x.png │ ├── icon-comment.png │ ├── icon-comment@2x.png │ ├── icon-downloaded~iphone.png │ ├── icon-downloaded~iphone@2x.png │ ├── icon-download~iphone.png │ ├── icon-download~iphone@2x.png │ ├── icon-like-r.png │ ├── icon-like-r@2x.png │ ├── icon-like-w~iphone.png │ ├── icon-like-w~iphone@2x.png │ ├── icon-like.png │ ├── icon-like@2x.png │ ├── icon-list~iphone.png │ ├── icon-list~iphone@2x.png │ ├── icon-mark~iphone.png │ ├── icon-mark~iphone@2x.png │ ├── icon-menu~iphone.png │ ├── icon-menu~iphone@2x.png │ ├── icon-pause~iphone.png │ ├── icon-pause~iphone@2x.png │ ├── icon-play~iphone.png │ ├── icon-play~iphone@2x.png │ ├── icon-share~iphone.png │ ├── icon-share~iphone@2x.png │ ├── logo-big.png │ ├── logo-big@2x.png │ ├── logo.png │ ├── logo@2x.png │ ├── navigationbar_back@2x.png │ ├── navigationbar_back@3x.png │ ├── photo~iphone.png │ ├── photo~iphone@2x.png │ ├── player-audio~iphone.png │ ├── player-audio~iphone@2x.png │ ├── player-slider-handle~iphone.png │ ├── player-slider-handle~iphone@2x.png │ ├── player-video~iphone.png │ ├── player-video~iphone@2x.png │ ├── player-w~iphone.png │ ├── player-w~iphone@2x.png │ ├── signin-weibo.png │ ├── signin-weibo@2x.png │ ├── signin-weixin.png │ ├── signin-weixin@2x.png │ ├── subscript.png │ ├── subscript@2x.png │ ├── timeline-listen~iphone.png │ ├── timeline-listen~iphone@2x.png │ ├── timeline-source~iphone.png │ ├── timeline-source~iphone@2x.png │ ├── unsubscript.png │ └── unsubscript@2x.png ├── root.js └── utils │ └── create-reducer.js ├── index.android.js ├── index.ios.js ├── index.js ├── ios ├── GCore-Bridging-Header.h ├── GCore-tvOS │ └── Info.plist ├── GCore-tvOSTests │ └── Info.plist ├── GCore.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ ├── GCore-tvOS.xcscheme │ │ └── GCore.xcscheme ├── GCore │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ └── LaunchScreen.xib │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── AppIcon1024x024.png │ │ │ ├── AppIcon20x20@2x.png │ │ │ ├── AppIcon20x20@3x.png │ │ │ ├── AppIcon29x29@2x.png │ │ │ ├── AppIcon29x29@3x.png │ │ │ ├── AppIcon40x40@2x.png │ │ │ ├── AppIcon40x40@3x.png │ │ │ ├── AppIcon60x60@2x.png │ │ │ ├── AppIcon60x60@3x.png │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── LaunchImage.launchimage │ │ │ ├── 1242x2208.png │ │ │ ├── 640x1136.png │ │ │ ├── 640x960.png │ │ │ ├── 750x1334.png │ │ │ └── Contents.json │ ├── Info.plist │ └── main.m ├── GCoreTests │ ├── GCoreTests.m │ └── Info.plist ├── bridge.swift ├── dump.swift └── empty.swift ├── package-lock.json ├── package.json ├── player-handler.js └── screenShot ├── pic1.png └── pic2.png /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react-native"] 3 | } 4 | -------------------------------------------------------------------------------- /.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | 11 | ; Ignore duplicate module providers 12 | ; For RN Apps installed via npm, "Libraries" folder is inside 13 | ; "node_modules/react-native" but in the source repo it is in the root 14 | .*/Libraries/react-native/React.js 15 | 16 | ; Ignore polyfills 17 | .*/Libraries/polyfills/.* 18 | 19 | ; Ignore metro 20 | .*/node_modules/metro/.* 21 | 22 | [include] 23 | 24 | [libs] 25 | node_modules/react-native/Libraries/react-native/react-native-interface.js 26 | node_modules/react-native/flow/ 27 | node_modules/react-native/flow-github/ 28 | 29 | [options] 30 | emoji=true 31 | 32 | module.system=haste 33 | 34 | munge_underscores=true 35 | 36 | 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\|pdf\)$' -> 'RelativeImageStub' 37 | 38 | module.file_ext=.js 39 | module.file_ext=.jsx 40 | module.file_ext=.json 41 | module.file_ext=.native.js 42 | 43 | suppress_type=$FlowIssue 44 | suppress_type=$FlowFixMe 45 | suppress_type=$FlowFixMeProps 46 | suppress_type=$FlowFixMeState 47 | 48 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 49 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 50 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 51 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 52 | 53 | unsafe.enable_getters_and_setters=true 54 | 55 | [version] 56 | ^0.61.0 57 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /.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/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | npm-debug.log 37 | yarn-error.log 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://docs.fastlane.tools/best-practices/source-control/ 50 | 51 | */fastlane/report.xml 52 | */fastlane/Preview.html 53 | */fastlane/screenshots 54 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-GCore 2 | a react-native app on iOS and android 3 | 4 | 运行平台: iOS & Android 5 | 6 | GCore基于机核app进行开发,只做学习不做商业用途,开发基于redux架构,适配Android和iOS,因react-native自身架构还有很多难处理,UI已经尽量和原版APP匹配,但是还是有不少妥协, 7 | 而Android部分UI和功能仍有些许缺陷,如有更好方案希望提出issues一起改进和学习。 8 | 9 | ## 部分截图 10 | ![pictureOne](https://github.com/LeonHwa/react-native-GCore/blob/master/screenShot/pic1.png) 11 | ![pictureTwo](https://github.com/LeonHwa/react-native-GCore/blob/master/screenShot/pic2.png) 12 | 13 | 14 | ## 已完成功能 15 | 可以登陆注册,进行评论,订阅和收藏喜欢的栏目,简单的下拉刷新,webView与RN交互,音频下载及本地播放 16 | 17 | ## 仍需改进 18 | - [ ] 第三方登陆 19 | - [ ] 安卓下载音频时UI卡顿 20 | - [ ] 删除评论功能 21 | 22 | ## 运行 23 | ``` 24 | $ git clone https://github.com/LeonHwa/react-native-GCore.git 25 | $ cd react-native-GCore 26 | $ npm install 27 | $ react-native run-ios/run-android 28 | ``` 29 | 30 | ## 框架 31 | [react-redux](https://github.com/reactjs/react-redux) 32 | 33 | [react-native-webview-bridge](https://github.com/alinz/react-native-webview-bridge) 34 | 35 | [react-native-audio-streaming](https://github.com/tlenclos/react-native-audio-streaming) 36 | 37 | [react-native-audio-streamer](https://github.com/indiecastfm/react-native-audio-streamer) 38 | 39 | [react-native-fs](https://github.com/itinance/react-native-fs) 40 | -------------------------------------------------------------------------------- /__tests__/index.android.js: -------------------------------------------------------------------------------- 1 | import 'react-native'; 2 | import React from 'react'; 3 | import Index from '../index.android.js'; 4 | 5 | // Note: test renderer must be required after react-native. 6 | import renderer from 'react-test-renderer'; 7 | 8 | it('renders correctly', () => { 9 | const tree = renderer.create( 10 | 11 | ); 12 | }); 13 | -------------------------------------------------------------------------------- /__tests__/index.ios.js: -------------------------------------------------------------------------------- 1 | import 'react-native'; 2 | import React from 'react'; 3 | import Index from '../index.ios.js'; 4 | 5 | // Note: test renderer must be required after react-native. 6 | import renderer from 'react-test-renderer'; 7 | 8 | it('renders correctly', () => { 9 | const tree = renderer.create( 10 | 11 | ); 12 | }); 13 | -------------------------------------------------------------------------------- /android/app/BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | lib_deps = [] 12 | 13 | for jarfile in glob(['libs/*.jar']): 14 | name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')] 15 | lib_deps.append(':' + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | 21 | for aarfile in glob(['libs/*.aar']): 22 | name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')] 23 | lib_deps.append(':' + name) 24 | android_prebuilt_aar( 25 | name = name, 26 | aar = aarfile, 27 | ) 28 | 29 | android_library( 30 | name = "all-libs", 31 | exported_deps = lib_deps, 32 | ) 33 | 34 | android_library( 35 | name = "app-code", 36 | srcs = glob([ 37 | "src/main/java/**/*.java", 38 | ]), 39 | deps = [ 40 | ":all-libs", 41 | ":build_config", 42 | ":res", 43 | ], 44 | ) 45 | 46 | android_build_config( 47 | name = "build_config", 48 | package = "com.gcore", 49 | ) 50 | 51 | android_resource( 52 | name = "res", 53 | package = "com.gcore", 54 | res = "src/main/res", 55 | ) 56 | 57 | android_binary( 58 | name = "app", 59 | keystore = "//android/keystores:debug", 60 | manifest = "src/main/AndroidManifest.xml", 61 | package_type = "debug", 62 | deps = [ 63 | ":app-code", 64 | ], 65 | ) 66 | -------------------------------------------------------------------------------- /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 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip 30 | 31 | # Do not strip any method/class that is annotated with @DoNotStrip 32 | -keep @com.facebook.proguard.annotations.DoNotStrip class * 33 | -keep @com.facebook.common.internal.DoNotStrip class * 34 | -keepclassmembers class * { 35 | @com.facebook.proguard.annotations.DoNotStrip *; 36 | @com.facebook.common.internal.DoNotStrip *; 37 | } 38 | 39 | -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * { 40 | void set*(***); 41 | *** get*(); 42 | } 43 | 44 | -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; } 45 | -keep class * extends com.facebook.react.bridge.NativeModule { *; } 46 | -keepclassmembers,includedescriptorclasses class * { native ; } 47 | -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; } 48 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; } 49 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; } 50 | 51 | -dontwarn com.facebook.react.** 52 | 53 | # TextLayoutBuilder uses a non-public Android constructor within StaticLayout. 54 | # See libs/proxy/src/main/java/com/facebook/fbui/textlayoutbuilder/proxy for details. 55 | -dontwarn android.text.StaticLayout 56 | 57 | # okhttp 58 | 59 | -keepattributes Signature 60 | -keepattributes *Annotation* 61 | -keep class okhttp3.** { *; } 62 | -keep interface okhttp3.** { *; } 63 | -dontwarn okhttp3.** 64 | 65 | # okio 66 | 67 | -keep class sun.misc.Unsafe { *; } 68 | -dontwarn java.nio.file.* 69 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 70 | -dontwarn okio.** 71 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/gcore/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.gcore; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. 9 | * This is used to schedule rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "GCore"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/gcore/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.gcore; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.react.ReactApplication; 6 | import com.theweflex.react.WeChatPackage; 7 | import guichaguri.trackplayer.TrackPlayer; 8 | import com.rnfs.RNFSPackage; 9 | import com.facebook.react.ReactNativeHost; 10 | import com.facebook.react.ReactPackage; 11 | import com.facebook.react.shell.MainReactPackage; 12 | import com.facebook.soloader.SoLoader; 13 | 14 | import java.util.Arrays; 15 | import java.util.List; 16 | 17 | public class MainApplication extends Application implements ReactApplication { 18 | 19 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 20 | @Override 21 | public boolean getUseDeveloperSupport() { 22 | return BuildConfig.DEBUG; 23 | } 24 | 25 | @Override 26 | protected List getPackages() { 27 | return Arrays.asList( 28 | new MainReactPackage(), 29 | new WeChatPackage(), 30 | new TrackPlayer(), 31 | new RNFSPackage() 32 | ); 33 | } 34 | 35 | @Override 36 | protected String getJSMainModuleName() { 37 | return "index"; 38 | } 39 | }; 40 | 41 | @Override 42 | public ReactNativeHost getReactNativeHost() { 43 | return mReactNativeHost; 44 | } 45 | 46 | @Override 47 | public void onCreate() { 48 | super.onCreate(); 49 | SoLoader.init(this, /* native exopackage */ false); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /android/app/src/main/java/wxapi/WXEntryActivity.java: -------------------------------------------------------------------------------- 1 | package wxapi; 2 | 3 | /** 4 | * Created by Leon.Hwa on 17/5/2. 5 | */ 6 | 7 | import android.app.Activity; 8 | import android.os.Bundle; 9 | import com.theweflex.react.WeChatModule; 10 | 11 | public class WXEntryActivity extends Activity { 12 | @Override 13 | protected void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | WeChatModule.handleIntent(getIntent()); 16 | finish(); 17 | } 18 | } -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | GCore 3 | 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /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:3.0.0' 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 "$rootDir/../node_modules/react-native/android" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jan 26 12:25:15 CST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip 7 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = "debug", 3 | properties = "debug.keystore.properties", 4 | store = "debug.keystore", 5 | visibility = [ 6 | "PUBLIC", 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /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/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'GCore' 2 | include ':react-native-wechat' 3 | project(':react-native-wechat').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-wechat/android') 4 | include ':react-native-track-player' 5 | project(':react-native-track-player').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-track-player/android') 6 | include ':react-native-fs' 7 | project(':react-native-fs').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fs/android') 8 | 9 | include ':app' 10 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GCore", 3 | "displayName": "GCore" 4 | } -------------------------------------------------------------------------------- /app/Lib/drawer/tweener.js: -------------------------------------------------------------------------------- 1 | import easingTypes from './tweenFunctions'; 2 | 3 | module.exports = function(config) { 4 | return new Tween(config); 5 | }; 6 | 7 | function Tween(config){ 8 | this._rafLoop = this._rafLoop.bind(this); 9 | this.terminate = this.terminate.bind(this); 10 | 11 | this._t0 = Date.now(); 12 | this._config = config; 13 | this._rafLoop(); 14 | } 15 | 16 | Tween.prototype._rafLoop = function() { 17 | if (this._break){ return; } 18 | 19 | var {duration, start, end, easingType} = this._config; 20 | var now = Date.now(); 21 | var elapsed = now - this._t0; 22 | 23 | if (elapsed >= duration){ 24 | this._config.onFrame(end); 25 | this._config.onEnd(); 26 | return; 27 | } 28 | 29 | var tweenVal = easingTypes[easingType](elapsed, start, end, duration); 30 | this._config.onFrame(tweenVal); 31 | 32 | requestAnimationFrame(this._rafLoop); 33 | }; 34 | 35 | Tween.prototype.terminate = function(){ 36 | this._break = true; 37 | }; 38 | -------------------------------------------------------------------------------- /app/actions/application.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import Constant from '../common/constants' 3 | const changeTab = (tab) => { 4 | return (dispatch) => { 5 | return Promise.resolve( 6 | dispatch({ 7 | type:Constant.APP.TAB, 8 | tab:tab 9 | })) 10 | } 11 | } 12 | const toNavigation = (targetComponent) => { 13 | return dispatch => { 14 | return Promise.resolve(dispatch({ 15 | type: Constant.APP.NAVIGATION, 16 | data: targetComponent 17 | })) 18 | } 19 | } 20 | 21 | const signin = (account) => { 22 | return dispatch => { 23 | return Promise.resolve(dispatch({ 24 | type: Constant.APP.SIGNIN, 25 | user: account, 26 | })) 27 | } 28 | } 29 | 30 | const signout = (targetComponent) => { 31 | return dispatch => { 32 | return Promise.resolve(dispatch({ 33 | type: Constant.APP.SIGNOUT, 34 | user: null, 35 | })) 36 | } 37 | } 38 | export default {changeTab,toNavigation,signin,signout} -------------------------------------------------------------------------------- /app/actions/article.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import Channel from '../channel' 3 | import Common from '../common/constants' 4 | const getAirticlePage = (page = 1) => { 5 | return(dispatch,store) => { 6 | dispatch(fetchingAirticle(page)) 7 | const channel = new Channel() 8 | return channel.getArticlePage(page) 9 | .then(data =>{ 10 | return dispatch({ 11 | type:Common.ARTICLE.INFO, 12 | data:data, 13 | page:page, 14 | isLoading:false, 15 | isLoadMore:false 16 | }) 17 | }) 18 | } 19 | } 20 | 21 | const fetchingAirticle = (page)=>{ 22 | var isLoading = false 23 | var isLoadMore = false 24 | if(page === 1){ 25 | isLoading = true, 26 | isLoadMore = false 27 | }else{ 28 | isLoading = false, 29 | isLoadMore =true 30 | } 31 | console.log('状态') 32 | return { 33 | type:Common.ARTICLE.INFO, 34 | isLoading:isLoading, 35 | isLoadMore:isLoadMore 36 | } 37 | } 38 | export default {getAirticlePage} -------------------------------------------------------------------------------- /app/actions/categories.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by leon on 2017/4/17. 3 | */ 4 | import Channel from '../channel' 5 | import Common from '../common/constants' 6 | const getCategories = () => { 7 | return(dispatch,store) => { 8 | const channel = new Channel() 9 | return channel.getCategories() 10 | .then(data =>{ 11 | return dispatch({ 12 | type:Common.CATEGORIES.INFO, 13 | data:data 14 | }) 15 | }) 16 | } 17 | } 18 | const getCategorieSubscriptInfo = (id) => { 19 | return(dispatch,store) => { 20 | const channel = new Channel() 21 | return channel.getCategorieSubscriptInfo(id) 22 | .then(data =>{ 23 | return dispatch({ 24 | type:Common.CATEGORIES.SUB, 25 | data:data 26 | }) 27 | }) 28 | } 29 | } 30 | 31 | const getCategorieDetail= (id,page=1) => { 32 | return(dispatch,store) => { 33 | const channel = new Channel() 34 | return channel.getCategorieDetail(id,page) 35 | .then(data =>{ 36 | return dispatch({ 37 | type:Common.CATEGORIES.DETAIL, 38 | data:data 39 | }) 40 | }) 41 | } 42 | } 43 | const clearSubscriptInfo = ()=>{ 44 | return dispatch({ 45 | type:Common.CATEGORIES.CLEAR 46 | }) 47 | } 48 | 49 | export default {getCategories,getCategorieDetail,getCategorieSubscriptInfo,clearSubscriptInfo} -------------------------------------------------------------------------------- /app/actions/comment.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import Channel from '../channel' 3 | const getComment = (type = 'hot',page = 1,id) => { 4 | 5 | var requestType = '' 6 | if(type === 'hot'){ 7 | requestType = Common.COMMENT.HOT 8 | }else{ 9 | requestType = Common.COMMENT.TIME 10 | } 11 | return(dispatch,store) => { 12 | dispatch(fetchingComment(page,requestType)) 13 | const channel = new Channel() 14 | return channel.getComment(type,page,id) 15 | .then(data =>{ 16 | console.log('dispatch' + requestType) 17 | return dispatch({ 18 | type:requestType, 19 | data:data, 20 | isLoading:false, 21 | isLoadMore:false, 22 | page:page 23 | }) 24 | }) 25 | } 26 | } 27 | const fetchingComment = (page,requestType)=>{ 28 | var isLoading = false 29 | var isLoadMore = false 30 | if(page === 1){ 31 | isLoading = true, 32 | isLoadMore = false 33 | }else{ 34 | isLoading = false, 35 | isLoadMore =true 36 | } 37 | console.log('状态') 38 | return { 39 | type:requestType, 40 | isLoading:isLoading, 41 | isLoadMore:isLoadMore 42 | } 43 | } 44 | export default {getComment} 45 | -------------------------------------------------------------------------------- /app/actions/download.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by leon on 2017/5/6. 3 | */ 4 | const downloadBegin = (pageInfo) => { 5 | 6 | return(dispatch,store) => { 7 | return dispatch({ 8 | type:Common.DOWNLOAD.BEGIN, 9 | data:pageInfo, 10 | }) 11 | } 12 | } 13 | const downloadEnd = () => { 14 | 15 | return(dispatch,store) => { 16 | return dispatch({ 17 | type:Common.DOWNLOAD.END, 18 | data:null, 19 | }) 20 | } 21 | } 22 | export default {downloadBegin,downloadEnd} 23 | -------------------------------------------------------------------------------- /app/actions/home.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/3/21. 3 | */ 4 | import Channel from '../channel' 5 | import Common from '../common/constants' 6 | /**获取轮播图*/ 7 | const getBanner = ()=>{ 8 | return(dispatch,store) => { 9 | const channel = new Channel() 10 | return channel.getBanner() 11 | .then(data =>{ 12 | return dispatch({ 13 | type:Common.HOME.BANNAR, 14 | data:data 15 | }) 16 | }) 17 | } 18 | 19 | } 20 | /**获取首页信息*/ 21 | const getHomePage = (page=1)=>{ 22 | return(dispatch,store) => { 23 | dispatch(fetchingHomePage(page)) 24 | const channel = new Channel() 25 | return channel.getHomePage(page) 26 | .then(data =>{ 27 | return dispatch({ 28 | type:Common.HOME.INFO, 29 | data:data, 30 | page:page, 31 | isLoading:false, 32 | isLoadMore:false 33 | }) 34 | }) 35 | } 36 | } 37 | 38 | const fetchingHomePage = (page)=>{ 39 | var isLoading = false 40 | var isLoadMore = false 41 | if(page === 1){ 42 | isLoading = true, 43 | isLoadMore = false 44 | }else{ 45 | isLoading = false, 46 | isLoadMore =true 47 | } 48 | console.log('状态') 49 | return { 50 | type:Common.HOME.INFO, 51 | isLoading:isLoading, 52 | isLoadMore:isLoadMore 53 | } 54 | } 55 | 56 | export default { 57 | getBanner, 58 | getHomePage, 59 | fetchingHomePage 60 | } 61 | 62 | -------------------------------------------------------------------------------- /app/actions/myMark.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/18. 3 | */ 4 | 5 | import Channel from '../channel' 6 | import Commom from '../common/constants' 7 | const getMyMark= (page) => { 8 | return(dispatch,store) => { 9 | const channel = new Channel() 10 | return channel.getMyMark(page) 11 | .then(data =>{ 12 | console.log(data) 13 | return dispatch({ 14 | type:Commom.MYMARK.INFO, 15 | data:data 16 | }) 17 | }) 18 | } 19 | } 20 | 21 | 22 | export default {getMyMark} -------------------------------------------------------------------------------- /app/actions/news.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import Channel from '../channel' 3 | const getNews = (page = 1) => { 4 | return(dispatch,store) => { 5 | dispatch(fetchingNews(page)) 6 | const channel = new Channel() 7 | return channel.getNews(page) 8 | .then(data =>{ 9 | return dispatch({ 10 | type:Common.NEWS.INFO, 11 | data:data, 12 | page:page, 13 | isLoading:false, 14 | isLoadMore:false 15 | }) 16 | }) 17 | } 18 | } 19 | const fetchingNews = (page)=>{ 20 | var isLoading = false 21 | var isLoadMore = false 22 | if(page === 1){ 23 | isLoading = true, 24 | isLoadMore = false 25 | }else{ 26 | isLoading = false, 27 | isLoadMore =true 28 | } 29 | console.log('状态') 30 | return { 31 | type:Common.NEWS.INFO, 32 | isLoading:isLoading, 33 | isLoadMore:isLoadMore 34 | } 35 | } 36 | export default {getNews} 37 | -------------------------------------------------------------------------------- /app/actions/pageInfo.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import Channel from '../channel' 3 | import Commom from '../common/constants' 4 | const getPageInfo = (id) => { 5 | return(dispatch,store) => { 6 | const channel = new Channel() 7 | return channel.getPageInfo(id) 8 | .then(data =>{ 9 | return dispatch({ 10 | type:Commom.PAGEINFO.INFO, 11 | data:data 12 | }) 13 | }) 14 | } 15 | } 16 | export default {getPageInfo} 17 | -------------------------------------------------------------------------------- /app/actions/play.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import Constant from '../common/constants' 3 | const show = (id,pageInfo) => { 4 | return (dispatch) => { 5 | console.log('显示') 6 | return Promise.resolve( 7 | dispatch({ 8 | type:Common.PLAY.SHOW, 9 | id:id, 10 | pageInfo:pageInfo, 11 | show:true 12 | })) 13 | } 14 | } 15 | const hidden = (id) => { 16 | console.log('隐藏') 17 | return dispatch => { 18 | return Promise.resolve(dispatch({ 19 | type:Common.PLAY.HIDDEN, 20 | id: id, 21 | show:false 22 | })) 23 | } 24 | } 25 | const play = (isPlay) => { 26 | 27 | return dispatch => { 28 | return Promise.resolve(dispatch({ 29 | type:Common.PLAY.PLAY, 30 | isPlay:isPlay 31 | })) 32 | } 33 | } 34 | export default {show,hidden,play} -------------------------------------------------------------------------------- /app/actions/radio.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/10. 3 | */ 4 | import Common from '../common/constants' 5 | import Channel from '../channel' 6 | /**获取轮播图*/ 7 | const getRadio = (page =1)=>{ 8 | return(dispatch,store) => { 9 | dispatch(fetchingRadio(page)) 10 | const channel = new Channel() 11 | return channel.getRadio(page) 12 | .then(data =>{ 13 | return dispatch({ 14 | type:Common.RADIO.INFO, 15 | data:data, 16 | isLoading:false, 17 | isLoadMore:false, 18 | page:page 19 | }) 20 | }) 21 | } 22 | 23 | } 24 | const fetchingRadio = (page)=>{ 25 | var isLoading = false 26 | var isLoadMore = false 27 | if(page === 1){ 28 | isLoading = true, 29 | isLoadMore = false 30 | }else{ 31 | isLoading = false, 32 | isLoadMore =true 33 | } 34 | return { 35 | type:Common.RADIO.INFO, 36 | isLoading:isLoading, 37 | isLoadMore:isLoadMore 38 | } 39 | } 40 | export default {getRadio} -------------------------------------------------------------------------------- /app/actions/subscript.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import Channel from '../channel' 3 | import Commom from '../common/constants' 4 | const getSubscript= (page) => { 5 | return(dispatch,store) => { 6 | const channel = new Channel() 7 | return channel.getSubscript(page) 8 | .then(data =>{ 9 | console.log(data) 10 | return dispatch({ 11 | type:Commom.SUBSCRIPT.INFO, 12 | data:data 13 | }) 14 | }) 15 | } 16 | } 17 | 18 | 19 | export default {getSubscript} -------------------------------------------------------------------------------- /app/actions/timeLine.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import Channel from '../channel' 3 | import Commom from '../common/constants' 4 | const getTimeLine = (id) => { 5 | return(dispatch,store) => { 6 | const channel = new Channel() 7 | return channel.getTimeLine(id) 8 | .then(data =>{ 9 | return dispatch({ 10 | type:Commom.TIMELINE.INFO, 11 | data:data 12 | }) 13 | }) 14 | } 15 | } 16 | const getTimeLineCategories = (page = 1) => { 17 | return(dispatch,store) => { 18 | const channel = new Channel() 19 | return channel.getTimeLineCategories(page) 20 | .then(data =>{ 21 | return dispatch({ 22 | type:Commom.TIMELINE.CATEGORY, 23 | data:data 24 | }) 25 | }) 26 | } 27 | } 28 | 29 | export default {getTimeLine,getTimeLineCategories} 30 | -------------------------------------------------------------------------------- /app/actions/video.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/10. 3 | */ 4 | 5 | import Common from '../common/constants' 6 | import Channel from '../channel' 7 | /**获取轮播图*/ 8 | const getVideo = (page =1)=>{ 9 | return(dispatch,store) => { 10 | dispatch(fetchingVideo(page)) 11 | const channel = new Channel() 12 | return channel.getVideo(page) 13 | .then(data =>{ 14 | return dispatch({ 15 | type:Common.VIDEO.INFO, 16 | data:data 17 | }) 18 | }) 19 | } 20 | 21 | } 22 | const fetchingVideo = (page)=>{ 23 | var isLoading = false 24 | var isLoadMore = false 25 | if(page === 1){ 26 | isLoading = true, 27 | isLoadMore = false 28 | }else{ 29 | isLoading = false, 30 | isLoadMore =true 31 | } 32 | console.log('状态') 33 | return { 34 | type:Common.VIDEO.INFO, 35 | isLoading:isLoading, 36 | isLoadMore:isLoadMore 37 | } 38 | } 39 | export default {getVideo} -------------------------------------------------------------------------------- /app/channel/DownloadManager.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import Storage from 'react-native-storage'; 4 | let instance = null; 5 | import MyStorage from '../channel/MyStorage' 6 | import RNFS from 'react-native-fs' 7 | 8 | let starage = new MyStorage() 9 | export default class DownloadManager { 10 | 11 | constructor() { 12 | if (!instance) { 13 | instance = this 14 | this.isDownloading = false 15 | } 16 | return instance 17 | } 18 | downloadFile(fromUrl,toFile,timeLine,pageInfo){ 19 | this.isDownloading = true 20 | this.fromUrl = fromUrl 21 | RNFS.downloadFile({ fromUrl: fromUrl, toFile: toFile ,background:true, 22 | progress:(res)=>{ 23 | var progress = (res.bytesWritten/res.contentLength) 24 | this.downloadInfo = {contentLength:res.contentLength,bytesWritten:res.bytesWritten,progress:progress,...pageInfo} 25 | if(progress === 1){ 26 | starage.saveAudioInfo(timeLine,{...pageInfo,contentLength:res.contentLength,localFile:true}); 27 | this.isDownloading = false 28 | } 29 | } 30 | }) 31 | } 32 | getDownloadProgress(info,callback){ 33 | if(callback){ 34 | callback(info) 35 | } 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /app/channel/MyStorage.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import { 3 | AsyncStorage 4 | }from 'react-native' 5 | import Storage from 'react-native-storage'; 6 | 7 | let storageInstance = null; 8 | let storage =new Storage({ 9 | size: 1000, 10 | storageBackend: AsyncStorage, 11 | defaultExpires: null, 12 | enableCache: true 13 | }) 14 | export default class MyStorage { 15 | 16 | constructor() { 17 | if(!storageInstance){ 18 | storageInstance = this 19 | } 20 | return storageInstance 21 | } 22 | 23 | loadAccount(callback){ 24 | storage.load({ 25 | key: 'account', 26 | id:0, 27 | // autoSync(默认为true)意味着在没有找到数据或数据过期时自动调用相应的sync方法 28 | autoSync: true, 29 | 30 | // syncInBackground(默认为true)意味着如果数据过期, 31 | // 在调用sync方法的同时先返回已经过期的数据。 32 | // 设置为false的话,则始终强制返回sync方法提供的最新数据(当然会需要更多等待时间)。 33 | syncInBackground: true, 34 | }).then(result=>{ 35 | if(result){ 36 | this.account = result 37 | console.log(this.account) 38 | } 39 | if(callback){ 40 | callback(result,null) 41 | } 42 | }).catch(err => { 43 | if(callback){ 44 | callback(null,err) 45 | } 46 | }) 47 | } 48 | saveAccount(account){ 49 | if(account){ 50 | this.account = account 51 | } 52 | storage.save({ 53 | key:'account', 54 | id:0, 55 | rawData:account, 56 | expires:null 57 | }) 58 | } 59 | signout(){ 60 | storage.remove({ 61 | key: 'account', 62 | id:0 63 | }); 64 | } 65 | 66 | saveAudioInfo(timeLine,pageInfo){ 67 | console.log('开始保存') 68 | storage.save({ 69 | key:'AudioInfo', 70 | id:pageInfo.id, 71 | rawData:{ 72 | timeLine:timeLine, 73 | pageInfo:pageInfo 74 | }, 75 | expires: null 76 | }) 77 | } 78 | getAudioInfo(id,callback){ 79 | storage.load({ 80 | key: 'AudioInfo', 81 | id:id, 82 | autoSync: true, 83 | syncInBackground: true 84 | }).then(result=>{ 85 | if(callback){ 86 | callback(result,null) 87 | } 88 | }).catch(err => { 89 | if(callback){ 90 | callback(null,err) 91 | } 92 | }) 93 | } 94 | removeAudioInfo(id){ 95 | storage.remove({ 96 | key: 'AudioInfo', 97 | id:id 98 | }); 99 | } 100 | getAllDataForKey(key,callback){ 101 | // 获取某个key下的所有数据 102 | storage.getAllDataForKey(key).then(res => { 103 | if(callback){ 104 | callback(res) 105 | } 106 | }); 107 | } 108 | 109 | } 110 | 111 | 112 | -------------------------------------------------------------------------------- /app/channel/NetTool.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by leon on 2017/4/13. 3 | */ 4 | //'auth_exclusive=dpkynzs2q0wm9o5gi1r83fcabthl4eu&auth_key=2451713064@qq.com&password=fander911&sourceType=app' 5 | 6 | const set_device_token_url = 'http://www.g-cores.com/api/set_device_token' 7 | const device_token = 'b3be092d57b5710c1a60bd85b876bf502f3849ee6e0c332e659bda63de580c68' 8 | const defresh_url = 'http://www.g-cores.com/api/users/defresh' 9 | /** 10 | * auth_exclusive dpkynzs2q0wm9o5gi1r83fcabthl4eu 11 | 0VzyZguVbX5nhpeQe6XC8g 12 | device_token 13 | 112872 14 | * */ 15 | const NetTool = { 16 | 17 | POST(url, params, callback){ 18 | fetch(url,{ 19 | method:'POST', 20 | body:params 21 | }) 22 | .then((response) => (response.json())) 23 | .then((jsonResponse) => { 24 | callback(jsonResponse,null) 25 | }) 26 | .catch((error)=>{ 27 | callback(null,error) 28 | }).catch(err => { 29 | console.warn(err.message); 30 | callback(null,error) 31 | }) 32 | }, 33 | 34 | setDevideToken(auth_token,user_id,callback){ 35 | let fromData = new FormData 36 | if(auth_token || user_id){ 37 | fromData.append('auth_token',auth_token) 38 | fromData.append('user_id',user_id) 39 | }else { 40 | fromData.append('user_id',0) 41 | } 42 | fromData.append('auth_exclusive','dpkynzs2q0wm9o5gi1r83fcabthl4eu') 43 | fromData.append('device_token',device_token) 44 | this.POST(set_device_token_url,fromData,(res,error )=>{ 45 | console.log(res) 46 | console.log(error) 47 | if(callback){ 48 | callback(res,error) 49 | } 50 | }) 51 | }, 52 | 53 | defresh(nickname,auth_token,callback){ 54 | 55 | let fromData = new FormData 56 | fromData.append('auth_token',auth_token) 57 | fromData.append('nickname',nickname) 58 | fromData.append('auth_exclusive','dpkynzs2q0wm9o5gi1r83fcabthl4eu') 59 | console.log(fromData) 60 | this.POST(defresh_url,fromData,(res,error )=>{ 61 | console.log(res) 62 | console.log(error) 63 | if(callback){ 64 | callback(res,error) 65 | } 66 | }) 67 | } 68 | } 69 | export default NetTool -------------------------------------------------------------------------------- /app/channel/address.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/3/21. 3 | */ 4 | import MyStorage from '../channel/MyStorage' 5 | let storage = new MyStorage() 6 | 7 | const address = { 8 | banner: (auth = Common.AUTH_KEY.auth_key) => { 9 | 10 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 11 | return `http://www.g-cores.com/api/originals/home_slideshow?auth_exclusive=${auth}`+ auth_token 12 | }, 13 | homePage:(page,auth = Common.AUTH_KEY.auth_key) => { 14 | 15 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 16 | return `http://www.g-cores.com/api/originals/home?page=${page}&auth_exclusive=${auth}`+ auth_token 17 | }, 18 | 19 | articlePage:(page = 1,auth = Common.AUTH_KEY.auth_key) =>{ 20 | 21 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 22 | return `http://www.g-cores.com/api/categories/1/originals?page=${page}&auth_exclusive=${auth}`+ auth_token 23 | }, 24 | news:(page,auth = Common.AUTH_KEY.auth_key ) =>{ 25 | 26 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 27 | return `http://www.g-cores.com/api/categories/2/originals?page=${page}&auth_exclusive=${auth}`+ auth_token 28 | }, 29 | articleDetail:(id,auth = Common.AUTH_KEY.auth_key) => { 30 | 31 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 32 | return `http://www.g-cores.com/api/originals/${id}/html_content?auth_exclusive=${auth}&auth_token= &quickdownload=1`+ auth_token 33 | }, 34 | newsDetail: (id,auth = Common.AUTH_KEY.auth_key) => { 35 | 36 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 37 | return `http://www.g-cores.com/api/originals/${id}/html_content?auth_exclusive=${auth}&auth_token=(null)&quickdownload=1`+ auth_token 38 | }, 39 | bannarDetail: (id,auth = Common.AUTH_KEY.auth_key) => { 40 | 41 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 42 | return `http://www.g-cores.com/api/originals/${id}/html_content?auth_exclusive=${auth}&auth_token=(null)&quickdownload=1`+ auth_token 43 | }, 44 | getComment :(type,page,id,auth = Common.AUTH_KEY.auth_key) => { 45 | 46 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 47 | return `http://www.g-cores.com/api/comments?auth_exclusive=${auth}&commentable_id=${id}&commentable_type=original&page=${page}&sort=${type}` 48 | }, 49 | getPageInfo:(id,auth = Common.AUTH_KEY.auth_key) => { 50 | 51 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 52 | return `http://www.g-cores.com/api/originals/${id}?auth_exclusive=${auth}` + auth_token 53 | }, 54 | getTimeLine:(id,auth = Common.AUTH_KEY.auth_key) => { 55 | 56 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 57 | return `http://www.g-cores.com/api/volumes/${id}/timelines?auth_exclusive=${auth}`+ auth_token 58 | }, 59 | getTimeLineCategories:(page = 1,auth = Common.AUTH_KEY.auth_key) => { 60 | 61 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 62 | return `http://www.g-cores.com/api/categories/9/originals?page=${page}&auth_exclusive=${auth}`+ auth_token 63 | }, 64 | getRadio:(page = 1,auth = Common.AUTH_KEY.auth_key) => { 65 | 66 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 67 | return `http://www.g-cores.com/api/categories/9/originals?page=${page}&auth_exclusive=${auth}`+ auth_token 68 | }, 69 | getVideo:(page = 1,auth = Common.AUTH_KEY.auth_key) => { 70 | 71 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 72 | return `http://www.g-cores.com/api/categories/8/originals?page=${page}&auth_exclusive=${auth}`+ auth_token 73 | }, 74 | getCategories:(auth = Common.AUTH_KEY.auth_key) => { 75 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 76 | return `http://www.g-cores.com/api/categories?auth_exclusive=${auth}`+ auth_token 77 | }, 78 | getCategorieDetail:(id,page,auth = Common.AUTH_KEY.auth_key) => { 79 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 80 | return `http://www.g-cores.com/api/categories/${id}/originals?page=${page}&auth_exclusive=${auth}`+ auth_token 81 | }, 82 | getCategorieSubscriptInfo:(id,auth = Common.AUTH_KEY.auth_key) => { 83 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 84 | return `http://www.g-cores.com/api/categories/${id}?auth_exclusive=${auth}`+ auth_token 85 | }, 86 | getSubscript:(page,auth = Common.AUTH_KEY.auth_key)=>{ 87 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 88 | return `http://www.g-cores.com/api/subscriptions/my_category_originals?page=${page}&auth_exclusive=${auth}`+ auth_token 89 | }, 90 | getMyMark:(page,auth = Common.AUTH_KEY.auth_key)=>{ 91 | const auth_token = storage.account ? `&auth_token=` + storage.account.auth_token:`` 92 | return `http://www.g-cores.com/api/originals/my_marked?page=${page}&auth_exclusive=${auth}`+ auth_token 93 | }, 94 | } 95 | export default address -------------------------------------------------------------------------------- /app/channel/producer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/3/22. 3 | */ 4 | const Producer = { 5 | getHomePageData : (data) => { 6 | 7 | } 8 | } 9 | export default {Producer} -------------------------------------------------------------------------------- /app/common/constants.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /** 3 | * Created by Leon.Hwa on 17/3/20. 4 | */ 5 | import {Dimensions, PixelRatio} from 'react-native' 6 | 7 | const APP = { 8 | TAB: 'APP.TAB', 9 | NAVIGATION:'APP.NAVIGATION', 10 | SIGNIN:'APP.SIGNIN', 11 | SIGNOUT:'APP.SIGNOUT', 12 | } 13 | 14 | const WINDOW = { 15 | width :Dimensions.get('window').width, 16 | height:Dimensions.get('window').height, 17 | onePR:1/PixelRatio.get() 18 | } 19 | 20 | const AUTH_KEY = { 21 | auth_key: 'dpkynzs2q0wm9o5gi1r83fcabthl4eu' 22 | } 23 | const HOME = { 24 | INFO: 'HOME.INFO', 25 | DETAIL: 'HOME.DETAIL', 26 | BANNAR:'HOME.BANNAR' 27 | } 28 | 29 | const NEWS = { 30 | INFO: 'NEWS.INFO', 31 | DETAIL: 'NEWS.DETAIL', 32 | } 33 | 34 | const ARTICLE = { 35 | INFO: 'ARTICLE.INFO', 36 | DETAIL: 'ARTICLE.DETAIL', 37 | } 38 | const COMMENT = { 39 | HOT: 'COMMENT.HOT', 40 | TIME: 'COMMENT.TIME', 41 | } 42 | const PAGEINFO = { 43 | INFO: 'PAGEINFO' 44 | } 45 | const TIMELINE = { 46 | INFO: 'TIMELINE.INFO', 47 | CATEGORY:'TIMELINE.CATEGORY', 48 | DOWNLOAD: 'TIMELINE.DOWNLOAD' 49 | } 50 | const PLAY = { 51 | SHOW: 'PLAY.SHOW', 52 | HIDDEN:'PLAY.HIDDEN', 53 | PLAY:'PLAY.PLAY' 54 | } 55 | const RADIO = { 56 | INFO: 'RADIO.INFO' 57 | } 58 | const VIDEO = { 59 | INFO: 'VIDEO.INFO' 60 | } 61 | 62 | const CATEGORIES = { 63 | INFO: 'CATEGORIES.INFO', 64 | DETAIL: 'CATEGORIES.DETAIL', 65 | SUB:'CATEGORIES.SUB', 66 | CLEAR:'CATEGORIES.CLEAR' 67 | } 68 | const SUBSCRIPT = { 69 | INFO: 'SUBSCRIPT.INFO', 70 | } 71 | const MYMARK = { 72 | INFO: 'MYMARK.INFO', 73 | } 74 | const DOWNLOAD = { 75 | BEGIN: 'DOWNLOAD.BEGIN', 76 | END: 'DOWNLOAD.END', 77 | } 78 | export default { 79 | APP, 80 | AUTH_KEY, 81 | WINDOW, 82 | HOME, 83 | ARTICLE, 84 | NEWS, 85 | COMMENT, 86 | PAGEINFO, 87 | TIMELINE, 88 | PLAY, 89 | RADIO, 90 | VIDEO, 91 | CATEGORIES, 92 | SUBSCRIPT, 93 | MYMARK, 94 | DOWNLOAD 95 | } -------------------------------------------------------------------------------- /app/components/airticle/Article.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { 3 | StyleSheet, 4 | Text, 5 | View, 6 | ListView, 7 | RefreshControl, 8 | ActivityIndicator, 9 | Platform 10 | } from 'react-native'; 11 | import Original from './Original' 12 | import Common from '../../common/constants' 13 | export default class Airticle extends Component { 14 | // 构造 15 | constructor(props) { 16 | super(props); 17 | // 初始状态 18 | this.state = { 19 | dataSource: new ListView.DataSource({ 20 | rowHasChanged: (row1, row2) => row1 !== row2 21 | }) 22 | } 23 | this.page = 1 24 | } 25 | componentDidMount() { 26 | const {actions} = this.props 27 | console.log(actions) 28 | actions.getAirticlePage() 29 | } 30 | 31 | renderRow(data,index){ 32 | return() 33 | } 34 | 35 | _onRefresh(){ 36 | const {actions} = this.props 37 | this.page = 1 38 | console.log('正在刷新') 39 | actions.getAirticlePage(this.page) 40 | } 41 | _onScrollEndDrag(event){ 42 | const {contentOffset, layoutMeasurement, contentSize} = event.nativeEvent; 43 | let contentSizeH = contentSize.height; 44 | let viewBottomY = contentOffset.y + layoutMeasurement.height; 45 | console.log(viewBottomY - contentSizeH) 46 | if((viewBottomY - contentSizeH)>=40|| (Platform.OS === 'android' && parseInt(viewBottomY - contentSizeH) === 0)){ 47 | const {article,actions} = this.props 48 | if(article.isLoadMore){ 49 | return 50 | } 51 | this.page++; 52 | actions.getAirticlePage(this.page ) 53 | } 54 | } 55 | render() { 56 | const {article} = this.props 57 | const refreshWord = article.isLoading ? '正在刷新':'下拉刷新' 58 | return ( 59 | 60 | 73 | } 74 | /> 75 | {article.isLoadMore && 76 | 77 | 78 | 正在加载更多的数据... 79 | 80 | } 81 | 82 | ); 83 | } 84 | } 85 | 86 | const styles = StyleSheet.create({ 87 | container: { 88 | flex: 1, 89 | justifyContent: 'center', 90 | alignItems: 'center', 91 | backgroundColor: '#ffffff', 92 | }, 93 | welcome: { 94 | fontSize: 20, 95 | textAlign: 'center', 96 | margin: 10, 97 | }, 98 | instructions: { 99 | textAlign: 'center', 100 | color: '#333333', 101 | marginBottom: 5, 102 | }, 103 | loadingContainer: { 104 | height:30, 105 | width:Common.WINDOW.width, 106 | justifyContent: 'center', 107 | alignItems: 'center', 108 | flexDirection: 'row' 109 | } 110 | }); 111 | 112 | -------------------------------------------------------------------------------- /app/components/category/Category.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { 3 | StyleSheet, 4 | Text, 5 | View, 6 | Image, 7 | ListView, 8 | TouchableHighlight, 9 | InteractionManager 10 | } from 'react-native'; 11 | import Common from '../../common/constants' 12 | import CategoryDetail from './CategoryDetail' 13 | import CommonNavigationBar from '../../containers/CommonNavigationBar' 14 | import CategoryCell from './CategoryCell' 15 | export default class Category extends Component { 16 | // 构造 17 | constructor(props) { 18 | super(props); 19 | // 初始状态 20 | this.state = { 21 | dataSource: new ListView.DataSource({ 22 | rowHasChanged: (row1, row2) => row1 !== row2 23 | }) 24 | } 25 | } 26 | componentDidMount() { 27 | const {actions} = this.props 28 | InteractionManager.runAfterInteractions(() => { 29 | actions.getCategories() 30 | }) 31 | 32 | } 33 | _selectRow(data){ 34 | this.props.navigator.push({ 35 | component:CategoryDetail, 36 | params:{ 37 | ...this.props, 38 | id:data.id, 39 | specific_type:data.specific_type 40 | } 41 | }) 42 | } 43 | _renderRow(data,index){ 44 | return( 45 | 48 | ) 49 | } 50 | _onBack(){ 51 | this.props.navigator.pop() 52 | } 53 | render() { 54 | const {categories} = this.props 55 | return ( 56 | 57 | 61 | 66 | 67 | 68 | ); 69 | } 70 | } 71 | 72 | const styles = StyleSheet.create({ 73 | container: { 74 | flex: 1, 75 | justifyContent: 'center', 76 | alignItems: 'center', 77 | backgroundColor: '#ffffff', 78 | }, 79 | cell: { 80 | flex:1 81 | }, 82 | cellBg:{ 83 | width:Common.WINDOW.width, 84 | height:160, 85 | justifyContent:'center', 86 | alignItems:'center' 87 | }, 88 | nameContainer:{ 89 | width:200, 90 | height:32, 91 | justifyContent:'center', 92 | alignItems:'center', 93 | backgroundColor:'rgba(255,255,255,0.2)', 94 | borderColor:'#fff', 95 | borderWidth:1 96 | }, 97 | name:{ 98 | color:'#fff', 99 | fontSize:18, 100 | lineHeight:30 101 | }, 102 | numbersContainer:{ 103 | flexDirection:'row', 104 | backgroundColor:'transparent', 105 | }, 106 | numText:{ 107 | color:'#fff', 108 | fontSize:12, 109 | margin:6 110 | } 111 | 112 | }); 113 | 114 | -------------------------------------------------------------------------------- /app/components/category/CategoryCell.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/19. 3 | */ 4 | import React,{Component} from 'react' 5 | import { 6 | View, 7 | Text, 8 | StyleSheet, 9 | Image, 10 | TouchableHighlight, 11 | ImageBackground 12 | }from 'react-native' 13 | import Common from '../../common/constants' 14 | 15 | 16 | export default class CategoryCell extends Component { 17 | 18 | _selectRow(){ 19 | const {selectRow,categorie} = this.props 20 | if(selectRow){ 21 | selectRow(categorie) 22 | } 23 | } 24 | render(){ 25 | const {categorie} = this.props 26 | return( 27 | 32 | 33 | 34 | 35 | {categorie.name} 36 | 37 | 38 | 文章数 {categorie.originals_num} 39 | 订阅数 {categorie.subscriptors_num} 40 | 41 | 42 | 43 | 44 | 45 | ) 46 | 47 | } 48 | } 49 | 50 | const styles = StyleSheet.create({ 51 | container: { 52 | flex: 1, 53 | justifyContent: 'center', 54 | alignItems: 'center', 55 | // backgroundColor: '#ffffff', 56 | }, 57 | cell: { 58 | flex:1 59 | }, 60 | cellBg:{ 61 | width:Common.WINDOW.width, 62 | height:160, 63 | justifyContent:'center', 64 | alignItems:'center' 65 | }, 66 | nameContainer:{ 67 | width:200, 68 | height:32, 69 | justifyContent:'center', 70 | alignItems:'center', 71 | backgroundColor:'rgba(255,255,255,0.2)', 72 | borderColor:'#fff', 73 | borderWidth:1 74 | }, 75 | name:{ 76 | color:'#fff', 77 | fontSize:18, 78 | lineHeight:30 79 | }, 80 | numbersContainer:{ 81 | flexDirection:'row', 82 | backgroundColor:'transparent', 83 | }, 84 | numText:{ 85 | color:'#fff', 86 | fontSize:12, 87 | margin:6 88 | } 89 | }) 90 | -------------------------------------------------------------------------------- /app/components/custom/SegmentedControl.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import React,{Component} from 'react' 3 | import { 4 | View, 5 | Text, 6 | StyleSheet, 7 | TouchableHighlight 8 | } from 'react-native' 9 | 10 | export default class SegmentedControl extends Component{ 11 | // 构造 12 | constructor(props) { 13 | super(props); 14 | // 初始状态 15 | this.state = { 16 | selectIndex:0 17 | }; 18 | } 19 | 20 | onPress = (index) => { 21 | this.setState({ 22 | selectIndex:index 23 | }) 24 | const {segmentDidSelectIndex } = this.props 25 | if(segmentDidSelectIndex){ 26 | segmentDidSelectIndex(index) 27 | } 28 | 29 | } 30 | render(){ 31 | const {values,itemWidth, height} = this.props 32 | 33 | return( 34 | 35 | 36 | {values.map((value,index) => { 37 | return( 38 | 42 | 43 | {value} 44 | 45 | 46 | ) 47 | }) 48 | } 49 | 50 | ) 51 | } 52 | } 53 | 54 | const styles = StyleSheet.create({ 55 | container:{ 56 | flexDirection:'row', 57 | borderColor:'#f7a37a', 58 | borderWidth:1, 59 | borderRadius:4, 60 | backgroundColor:'yellow', 61 | overflow:'hidden', 62 | alignItems:'center', 63 | justifyContent:'center', 64 | }, 65 | itemView: { 66 | flex:1, 67 | flexDirection:'row', 68 | alignItems:'center', 69 | justifyContent:'center', 70 | }, 71 | itemText:{ 72 | fontSize:14, 73 | textAlign:'center' 74 | } 75 | }) 76 | 77 | -------------------------------------------------------------------------------- /app/components/home/Home.js: -------------------------------------------------------------------------------- 1 | 2 | import React, { Component } from 'react'; 3 | import { 4 | StyleSheet, 5 | Text, 6 | View, 7 | PropTypes, 8 | TouchableHighlight, 9 | ListView, 10 | ScrollView, 11 | Image, 12 | RefreshControl, 13 | ActivityIndicator, 14 | InteractionManager, 15 | Platform, 16 | } from 'react-native'; 17 | 18 | import HomeBannar from './HomeBannar' 19 | import Original from '../airticle/Original' 20 | import NewsScrooll from './NewsScrooll' 21 | 22 | 23 | import Common from '../../common/constants' 24 | 25 | import Loading from '../other/Loading' 26 | 27 | 28 | export default class Home extends Component { 29 | // 构造 30 | constructor(props) { 31 | super(props); 32 | // 初始状态 33 | this.state = { 34 | dataSource:new ListView.DataSource({ 35 | rowHasChanged:(row1,row2) => row1 !== row2 36 | }), 37 | canScroll:true 38 | }; 39 | this.page = 1 40 | } 41 | 42 | fatherScrollToTop(ret){ 43 | this.setState({ 44 | canScroll:true 45 | }) 46 | } 47 | 48 | componentDidMount() { 49 | const {actions} = this.props 50 | InteractionManager.runAfterInteractions(()=>{ 51 | actions.getHomePage(this.page) 52 | actions.getBanner() 53 | }) 54 | } 55 | 56 | _renderRow(row){ 57 | const type = row.type 58 | if(type === 'original'){ 59 | return( 60 | 61 | ) 62 | }else if(type === 'news'){ 63 | return() 64 | } else if(type === 'categories'){ 65 | return() 66 | } 67 | 68 | return() 69 | } 70 | 71 | _onRefresh(){ 72 | const {actions} = this.props 73 | this.page = 1 74 | // console.log('正在刷新') 75 | actions.getHomePage(this.page) 76 | } 77 | _onScrollEndDrag(event){ 78 | const {contentOffset, layoutMeasurement, contentSize} = event.nativeEvent; 79 | let contentSizeH = contentSize.height; 80 | //layoutMeasurement.height 是listView的高度(小于 window.height) 81 | let viewBottomY = contentOffset.y + layoutMeasurement.height; 82 | 83 | console.log(viewBottomY - contentSizeH) 84 | if((viewBottomY - contentSizeH)>=40 || (Platform.OS === 'android' && parseInt(viewBottomY - contentSizeH) === 0)){ 85 | const {actions,homeInfo} = this.props 86 | if(homeInfo.isLoadMore){ 87 | return 88 | } 89 | this.page++; 90 | actions.getHomePage(this.page ) 91 | } 92 | 93 | } 94 | _renderHeader(ret){ 95 | return( 96 | this.header = c} 98 | {...this.props} 99 | /> 100 | ) 101 | } 102 | render(){ 103 | const {homeInfo} = this.props 104 | console.log(homeInfo) 105 | const refreshWord = homeInfo.isLoading ? '正在刷新':'下拉刷新' 106 | return ( 107 | 108 | {homeInfo&& this.listView = c} 110 | dataSource={this.state.dataSource.cloneWithRows(homeInfo.data)} 111 | enableEmptySections={true} 112 | renderRow={this._renderRow.bind(this)} 113 | style={styles.listView} 114 | onScrollEndDrag = {this._onScrollEndDrag.bind(this)} 115 | scrollEnabled={this.state.canScroll} 116 | renderHeader={this._renderHeader.bind(this)} 117 | refreshControl={ 118 | 124 | } 125 | /> 126 | } 127 | {homeInfo.isLoadMore && 128 | 129 | 130 | 加载中... 131 | 132 | } 133 | 134 | 135 | ); 136 | } 137 | } 138 | Home.propTypes = { 139 | application:React.PropTypes.object, 140 | bannar:React.PropTypes.object, 141 | homeInfo:React.PropTypes.object, 142 | actions:React.PropTypes.object 143 | } 144 | 145 | const styles = StyleSheet.create({ 146 | container: { 147 | flex: 1, 148 | backgroundColor: '#fff', 149 | }, 150 | listView: { 151 | flex:1 152 | }, 153 | bannar:{ 154 | height:250, 155 | width:Common.WINDOW.width 156 | }, 157 | loadingContainer: { 158 | height:30, 159 | width:Common.WINDOW.width, 160 | justifyContent: 'center', 161 | alignItems: 'center', 162 | flexDirection: 'row' 163 | } 164 | }); 165 | 166 | 167 | -------------------------------------------------------------------------------- /app/components/home/HomeBannar.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import React, { Component } from 'react'; 4 | import { 5 | StyleSheet, 6 | View, 7 | Text, 8 | PropTypes, 9 | TouchableHighlight, 10 | ScrollView, 11 | Image 12 | } from 'react-native'; 13 | import Commom from '../../common/constants' 14 | import ArticleDetail from '../airticle/ArticleDetail' 15 | 16 | import Carousel from '../../Lib/Carousel' 17 | export class Page extends Component{ 18 | renderPageCircle(){ 19 | const {page} = this.props 20 | var indicators = [] 21 | var style 22 | for( var i = 0 ; i < page.pageCount; i++){ 23 | style = (i === page.currentPage) ? {color:'#ffffff'} :{color:'rgba(255, 255, 255, 0.4)'} 24 | indicators.push( 25 | 26 | ) 27 | } 28 | return indicators 29 | } 30 | render(){ 31 | return( 32 | 33 | {this.renderPageCircle()} 34 | 35 | ) 36 | } 37 | 38 | } 39 | Page.propTypes = { 40 | page:React.PropTypes.object 41 | } 42 | 43 | export default class HomeBannar extends Component{ 44 | // 构造 45 | constructor(props) { 46 | super(props); 47 | // 初始状态 48 | this.state = { 49 | currentPage:0 50 | }; 51 | } 52 | _onTouchEnd(event){ 53 | var offset = event.nativeEvent.contentOffset.x 54 | var index = Math.floor(offset/Commom.WINDOW.width) 55 | this.setState({ 56 | currentPage:index 57 | }) 58 | } 59 | _onPress(bannar){ 60 | const {navigator,comment} = this.props 61 | if(navigator){ 62 | navigator.push({ 63 | name:'BannarDetail', 64 | component:ArticleDetail, 65 | params : {...this.props,likes_num:bannar.likes_num,id:bannar.original_id} 66 | }) 67 | 68 | } 69 | } 70 | render(){ 71 | const {bannar} = this.props 72 | return( 73 | 74 | { bannar && {}} 80 | autoplay = {true} 81 | bullets = {true} 82 | bulletStyle = {{backgroundColor: 'rgba(255, 255, 255, 0.4)', borderColor:'rgba(255, 255, 255, 0.4)'}} 83 | > 84 | { bannar.data.map((data, index) => { 85 | return ( 86 | 91 | 92 | 93 | ) 94 | }) 95 | } 96 | 97 | } 98 | 99 | 100 | 101 | 102 | ) 103 | } 104 | 105 | } 106 | 107 | HomeBannar.propTypes = { 108 | bannar:React.PropTypes.object 109 | } 110 | 111 | const styles = StyleSheet.create({ 112 | container: { 113 | height:220, 114 | width:Commom.WINDOW.width 115 | }, 116 | scroolView:{ 117 | flex:1 118 | }, 119 | image:{ 120 | height:220, 121 | width:Commom.WINDOW.width 122 | }, 123 | page:{ 124 | width:Commom.WINDOW.width, 125 | height:30, 126 | flexDirection:'row', 127 | justifyContent:'center', 128 | position:'absolute', 129 | bottom:10, 130 | alignItems:'center', 131 | backgroundColor:'transparent' 132 | } 133 | }); -------------------------------------------------------------------------------- /app/components/news/News.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { 3 | StyleSheet, 4 | Text, 5 | View, 6 | ListView, 7 | RefreshControl, 8 | ActivityIndicator, 9 | Platform 10 | } from 'react-native'; 11 | import NewsCell from './NewsCell' 12 | import Common from '../../common/constants' 13 | export default class News extends Component { 14 | // 构造 15 | constructor(props) { 16 | super(props); 17 | // 初始状态 18 | this.state = { 19 | dataSource: new ListView.DataSource({ 20 | rowHasChanged: (row1, row2) => row1 !== row2 21 | }) 22 | } 23 | this.page = 1 24 | } 25 | componentDidMount() { 26 | const {actions} = this.props 27 | console.log(actions) 28 | actions.getNews(this.page) 29 | } 30 | 31 | renderRow(data,index){ 32 | 33 | return() 34 | } 35 | 36 | _onRefresh(){ 37 | const {actions} = this.props 38 | this.page = 1 39 | console.log('正在刷新') 40 | actions.getNews(this.page) 41 | } 42 | _onScrollEndDrag(event){ 43 | 44 | const {contentOffset, layoutMeasurement, contentSize} = event.nativeEvent; 45 | let contentSizeH = contentSize.height; 46 | let viewBottomY = contentOffset.y + layoutMeasurement.height; 47 | 48 | console.log(viewBottomY - contentSizeH) 49 | if((viewBottomY - contentSizeH)>=40|| (Platform.OS === 'android' && parseInt(viewBottomY - contentSizeH) === 0)){ 50 | const {news,actions} = this.props 51 | if(news.isLoadMore){ 52 | return 53 | } 54 | this.page++; 55 | actions.getNews(this.page ) 56 | } 57 | } 58 | render() { 59 | const {news} = this.props 60 | const refreshWord = news.isLoading ? '正在刷新':'下拉刷新' 61 | return ( 62 | 63 | 76 | } 77 | /> 78 | {news.isLoadMore && 79 | 80 | 81 | 正在加载更多的数据... 82 | 83 | } 84 | 85 | ); 86 | } 87 | } 88 | 89 | const styles = StyleSheet.create({ 90 | container: { 91 | flex: 1, 92 | justifyContent: 'center', 93 | alignItems: 'center', 94 | backgroundColor: '#ffffff', 95 | }, 96 | welcome: { 97 | fontSize: 20, 98 | textAlign: 'center', 99 | margin: 10, 100 | }, 101 | instructions: { 102 | textAlign: 'center', 103 | color: '#333333', 104 | marginBottom: 5, 105 | }, 106 | loadingContainer: { 107 | height:30, 108 | width:Common.WINDOW.width, 109 | justifyContent: 'center', 110 | alignItems: 'center', 111 | flexDirection: 'row' 112 | } 113 | }); 114 | 115 | -------------------------------------------------------------------------------- /app/components/news/NewsCell.js: -------------------------------------------------------------------------------- 1 | import React,{Component} from 'react' 2 | import { 3 | View, 4 | Text, 5 | StyleSheet, 6 | Image, 7 | TouchableHighlight 8 | }from 'react-native' 9 | import Common from '../../common/constants' 10 | import ArticleDetail from '../airticle/ArticleDetail' 11 | 12 | export default class NewsCell extends Component { 13 | 14 | onPress(news){ 15 | const {navigator} = this.props 16 | // console.log(news) 17 | if(navigator){ 18 | navigator.push({ 19 | name:'ArticleDetail', 20 | component:ArticleDetail, 21 | params:{ 22 | ...this.props, 23 | likes_num:news.likes_num, 24 | id:news.id 25 | } 26 | 27 | }) 28 | } 29 | } 30 | render(){ 31 | const {newsList} = this.props 32 | return( 33 | 37 | 38 | 39 | 40 | 41 | 42 | {newsList.title} 43 | {newsList.desc} 44 | 45 | {newsList.category.name} 46 | 47 | {newsList.likes_num} 48 | 49 | {newsList.comments_num} 50 | 51 | 52 | 53 | 54 | 55 | ) 56 | 57 | } 58 | } 59 | 60 | const styles = StyleSheet.create({ 61 | container: { 62 | width: Common.WINDOW.width, 63 | height: 106, 64 | flexDirection: 'row', 65 | borderBottomColor:'#c8c8c8', 66 | borderBottomWidth:0.5 67 | }, 68 | image:{ 69 | flex:1, 70 | marginBottom:6 71 | }, 72 | leftZone: { 73 | flex: 1, 74 | paddingLeft:11, 75 | paddingTop:10, 76 | paddingBottom:17, 77 | paddingRight:7 78 | }, 79 | 80 | rightZone: { 81 | flex: 2, 82 | justifyContent:'space-around', 83 | paddingLeft:5, 84 | paddingRight:20, 85 | paddingTop:3, 86 | paddingBottom:5 87 | }, 88 | title:{ 89 | fontSize:15, 90 | color:'#444444' 91 | }, 92 | desc:{ 93 | fontSize:11, 94 | color:'#888888' 95 | }, 96 | bottomView:{ 97 | // height:20, 98 | flexDirection:'row', 99 | alignItems:'center' 100 | }, 101 | category:{ 102 | fontSize:12, 103 | color:'#888888' 104 | }, 105 | LCIcon:{ 106 | marginLeft:6, 107 | width:12, 108 | height:11 109 | }, 110 | LCNum:{ 111 | marginLeft:6, 112 | fontSize:10, 113 | color:'#888888' 114 | } 115 | }) -------------------------------------------------------------------------------- /app/components/other/Blank.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/3/27. 3 | */ 4 | import React,{Component} from 'react' 5 | import { 6 | View, 7 | Text, 8 | StyleSheet 9 | }from 'react-native' 10 | 11 | export default class Blank extends Component{ 12 | 13 | render(){ 14 | 15 | return( 16 | 17 | blank 18 | 19 | ) 20 | } 21 | } 22 | const styles = StyleSheet.create({ 23 | container: { 24 | width:44, 25 | height:44, 26 | backgroundColor:'red' 27 | } 28 | }) -------------------------------------------------------------------------------- /app/components/other/DateHandel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/25. 3 | */ 4 | 5 | //2017-05-11 09:48:33 6 | function parseDate(date) { 7 | var isoExp, parts; 8 | isoExp = /^\s*(\d{4})-(\d\d)-(\d\d)\s(\d\d):(\d\d):(\d\d)\s*$/; 9 | try { 10 | parts = isoExp.exec(date); 11 | } catch(e) { 12 | return null; 13 | } 14 | if (parts) { 15 | date = new Date(parts[1], parts[2] - 1, parts[3], parts[4], parts[5], parts[6]); 16 | } else { 17 | return null; 18 | } 19 | return date; 20 | } 21 | 22 | /** 23 | * 由于浏览器内核不一样 直接 new Date(date) 在safari 和 firfox 得到的是invalid 24 | * */ 25 | const parse = (date) =>{ 26 | // console.log(date) 27 | var d = parseDate(date) 28 | 29 | let year = d.getYear() 30 | let month = d.getMonth() 31 | let day = d.getDate() 32 | let hour = d.getHours() 33 | let min = d.getMinutes() 34 | 35 | 36 | let now = new Date() 37 | 38 | let yeal_del = now.getYear() - year 39 | let month_del = now.getMonth() - month 40 | var day_del = now.getDate() - day 41 | let hour_del = now.getHours() - hour 42 | let min_del = now.getMinutes() - min 43 | 44 | if(now.getYear() > year){ 45 | if(yeal_del === 1){ 46 | month_del = 12 - month + now.getMonth() 47 | return `${month_del}个月前` 48 | } 49 | return `${yeal_del}年前` 50 | }else{//月 51 | if(month_del > 1){ 52 | return `${month_del}个月前` 53 | }else if(month_del === 1){ 54 | day_del = 30 - day + now.getDate() 55 | } 56 | 57 | if(day_del >= 7){ 58 | let we = parseInt(day_del/7) 59 | return `${we}周前` 60 | 61 | }else if(day_del >= 1 && day_del < 7 ){ 62 | if(day_del == 1){ 63 | let hour_del = (24 - hour) + now.getHours() 64 | if(hour_del > 24){ 65 | return `昨天` 66 | } 67 | return `${hour_del}小时前` 68 | } 69 | return `${day_del}天前` 70 | 71 | 72 | }else {//小时 73 | 74 | if(hour_del > 1 ){ 75 | return `${hour_del}小时前` 76 | }else if(hour_del === 1){ 77 | let min_del = (60 - min) + now.getMinutes() 78 | 79 | if(min_del === 60){ 80 | return '1小时前' 81 | }else { 82 | return `${min_del}分钟前` 83 | } 84 | }else if(hour_del === 0){ 85 | 86 | if(min_del >= 1){ 87 | return `${min_del}分钟前` 88 | }else if(min_del === 0){ 89 | console.log(date + '===>' + day) 90 | console.log(now + '===>' + now.getDate()) 91 | return '刚刚' 92 | }else{ 93 | let day_del = now.getDate() - day 94 | console.log(day_del) 95 | return date 96 | } 97 | }else{ 98 | let day_del = now.getDate() - day 99 | console.log(day_del) 100 | return date 101 | } 102 | } 103 | } 104 | } 105 | export default {parse} -------------------------------------------------------------------------------- /app/components/other/Loading.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/20. 3 | */ 4 | import React from 'react'; 5 | import { 6 | StyleSheet, 7 | View, 8 | Text, 9 | ActivityIndicator 10 | } from 'react-native'; 11 | 12 | export default class Loading extends React.Component { 13 | render() { 14 | if (!this.props.isShow) return null; 15 | 16 | return ( 17 | 18 | 19 | 20 | 加载中…… 21 | 22 | 23 | ) 24 | } 25 | } 26 | 27 | Loading.propTypes = { 28 | isShow: React.PropTypes.bool 29 | } 30 | 31 | const styles = StyleSheet.create({ 32 | container: { 33 | position: 'absolute', 34 | top: 0, 35 | left: 0, 36 | right: 0, 37 | bottom: 0, 38 | justifyContent: 'center', 39 | alignItems: 'center' 40 | }, 41 | loading: { 42 | backgroundColor: 'black', 43 | height: 80, 44 | width: 100, 45 | borderRadius: 10, 46 | justifyContent: 'center', 47 | alignItems: 'center', 48 | }, 49 | loadingTitle: { 50 | marginTop: 10, 51 | fontSize: 14, 52 | color: 'white' 53 | } 54 | }) -------------------------------------------------------------------------------- /app/components/other/MusicTool.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/6. 3 | */ 4 | import React,{Component} from 'react' 5 | import { 6 | View, 7 | Image, 8 | StyleSheet, 9 | TouchableHighlight, 10 | Animated, 11 | Easing , //引入Easing渐变函数 12 | DeviceEventEmitter 13 | }from 'react-native' 14 | import Blank from './Blank' 15 | export default class MusicTool extends Component { 16 | // 构造 17 | constructor(props) { 18 | super(props); 19 | // 初始状态 20 | this.state = { 21 | rotateValue: new Animated.Value(0) 22 | }; 23 | } 24 | componentDidMount() { 25 | //在初始化渲染执行之后立刻调用动画执行函数 26 | this.startAnimation(); 27 | } 28 | 29 | startAnimation(){ 30 | this.state.rotateValue.setValue(0); 31 | Animated.timing(this.state.rotateValue, 32 | {toValue:1, 33 | duration:10000, 34 | easing: Easing.out(Easing.linear),//线性变化,匀速旋转 35 | isInteraction: false,//加入此参数可解决阻塞InteractionManager.runAfterInteractions,官方文档上无此参数说明 36 | } 37 | ).start(()=>this.startAnimation() ) 38 | } 39 | 40 | _onPress(){ 41 | const {play} = this.props 42 | if(play.show){ 43 | DeviceEventEmitter.emit('timeLine',play) 44 | } 45 | 46 | } 47 | render(){ 48 | const {play} = this.props 49 | // console.log(play) 50 | return( 51 | 52 | { play.show && 55 | 63 | 64 | 65 | } 66 | 67 | ) 68 | } 69 | } 70 | const styles = StyleSheet.create({ 71 | container:{ 72 | 73 | }, 74 | music:{ 75 | position:'absolute', 76 | borderRadius:22, 77 | right:10, 78 | bottom:60, 79 | width:44, 80 | height:44 81 | } 82 | }) -------------------------------------------------------------------------------- /app/components/other/Rename.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by leon on 2017/4/8. 3 | */ 4 | import React,{Component} from 'react' 5 | import { 6 | View, 7 | Text, 8 | StyleSheet, 9 | Image, 10 | TouchableHighlight, 11 | TextInput, 12 | ScrollView, 13 | Alert 14 | }from 'react-native' 15 | import Constants from '../../common/constants' 16 | import NetTool from '../../channel/NetTool' 17 | import MyStorage from '../../channel/MyStorage' 18 | 19 | export default class Rename extends Component { 20 | 21 | // 构造 22 | constructor(props) { 23 | super(props); 24 | // 初始状态 25 | this.state = { 26 | name:'' 27 | }; 28 | } 29 | _cancel(){ 30 | 31 | 32 | } 33 | _changeName(){ 34 | const {auth_token,user,actions} = this.props 35 | if(this.state.name.length === 0){ 36 | Alert.alert('提示','昵称不能为空',[{text:'确定',onPress:()=>{console.log('sure')} }]) 37 | return; 38 | } 39 | NetTool.defresh(this.state.name,auth_token,(res,err)=>{ 40 | 41 | if(res){ 42 | console.log(res) 43 | if(res.status === 0){ 44 | Alert.alert('提示',res.error,[{text:'确定',onPress:()=>{console.log('sure')} }]) 45 | return; 46 | }else if(res.status === 1){ 47 | var newUser = {...user,is_fresh:false, 48 | nickname:this.state.name} 49 | actions.signin(newUser) 50 | NetTool.setDevideToken(newUser.auth_token,newUser.id) 51 | this.props.navigator.pop() 52 | } 53 | 54 | } 55 | }) 56 | } 57 | render(){ 58 | return( 59 | 60 | 61 | 最后一步 62 | 63 | this.setState({name:text})} 65 | maxLength = {20} 66 | multiline={false} 67 | underlineColorAndroid="transparent" 68 | /> 69 | 70 | 请填写你的昵称,以完成注册 71 | 74 | 完成 75 | 76 | 77 | 78 | ) 79 | } 80 | } 81 | 82 | 83 | const styles = StyleSheet.create({ 84 | twoContainView:{ 85 | flex:1, 86 | alignItems:'center', 87 | backgroundColor:'#ffffff', 88 | justifyContent:'center' 89 | }, 90 | singinBtn:{ 91 | 92 | borderRadius:6, 93 | width:100, 94 | height:36, 95 | marginTop:50, 96 | justifyContent:'center', 97 | borderColor:'#777777', 98 | borderWidth:1 99 | }, 100 | singinText:{ 101 | color:'#777777', 102 | textAlign:'center', 103 | }, 104 | 105 | text:{ 106 | alignSelf:'center', 107 | marginTop:20, 108 | height: 30, 109 | width:220, 110 | padding:0 111 | }, 112 | btnText:{ 113 | color:'#555555', 114 | marginTop:26 115 | }, 116 | iconContainer: { 117 | flexDirection: 'row', 118 | justifyContent: 'space-around', 119 | width:150, 120 | height:80, 121 | marginTop:50 122 | }, 123 | bottomText:{ 124 | color:'#555555', 125 | marginTop:30 126 | } 127 | }) -------------------------------------------------------------------------------- /app/components/other/TLView.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/3/27. 3 | */ 4 | import React,{Component} from 'react' 5 | import { 6 | View, 7 | Text, 8 | StyleSheet 9 | }from 'react-native' 10 | import {Navigator} from 'react-native-deprecated-custom-components' 11 | import Blank from './Blank' 12 | import MusicTool from './MusicTool' 13 | export default class TLView extends Component{ 14 | 15 | _configureScene = route => { 16 | //有这句后后面修改 sceneConfig 才有效 否则不起作用 17 | if (route.sceneConfig) return route.sceneConfig 18 | return { 19 | ...Navigator.SceneConfigs.PushFromRight, 20 | // gestures: {} // 禁用左滑返回手势 21 | } 22 | } 23 | 24 | _renderScene = (route, navigator) => { 25 | let Component = route.component 26 | return 27 | } 28 | 29 | render(){ 30 | 31 | return( 32 | 33 | 38 | 39 | ) 40 | } 41 | } 42 | 43 | const styles = StyleSheet.create({ 44 | container: { 45 | position:'absolute', 46 | width:44, 47 | height:44, 48 | right:20, 49 | bottom:60, 50 | borderRadius:22, 51 | } 52 | }) -------------------------------------------------------------------------------- /app/components/other/custom/MyIcon.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/5/9. 3 | */ 4 | import React, { Component } from 'react'; 5 | import { 6 | StyleSheet, 7 | Text, 8 | View, 9 | Image, 10 | TouchableHighlight 11 | } from 'react-native'; 12 | 13 | export default class MyIcon extends Component { 14 | 15 | render() { 16 | 17 | return ( 18 | 19 | 23 | 26 | 27 | 28 | 29 | ); 30 | } 31 | } 32 | 33 | const styles = StyleSheet.create({ 34 | container: { 35 | flex: 1, 36 | justifyContent: 'center', 37 | alignItems: 'center', 38 | backgroundColor: '#ffffff', 39 | }, 40 | 41 | }); 42 | 43 | -------------------------------------------------------------------------------- /app/components/other/me/MyMark.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/18. 3 | */ 4 | import React, { Component } from 'react'; 5 | import { 6 | StyleSheet, 7 | Text, 8 | View, 9 | ListView 10 | } from 'react-native'; 11 | 12 | import Original from '../../airticle/Original' 13 | import NewsCell from '../../news/NewsCell' 14 | import CommonNavigationBar from '../../../containers/CommonNavigationBar' 15 | export default class MyMark extends Component { 16 | // 构造 17 | constructor(props) { 18 | super(props); 19 | // 初始状态 20 | this.state = { 21 | dataSource: new ListView.DataSource({ 22 | rowHasChanged: (row1, row2) => row1 !== row2 23 | }) 24 | } 25 | } 26 | componentDidMount() { 27 | const {actions} = this.props 28 | console.log(actions) 29 | actions.getMyMark(1) 30 | } 31 | _onBack(){ 32 | this.props.navigator.pop() 33 | } 34 | renderRow(data,index){ 35 | const type = data.type 36 | if(type === 'Article' || type === 'Volume'){ 37 | var cell_type = type === 'Article' ? 'default':type 38 | if(type=='Volume' && data.media.flv){ 39 | cell_type = 'video' 40 | } 41 | return( 42 | 43 | ) 44 | }else if(type === 'news'){ 45 | return( 46 | 47 | ) 48 | } 49 | return() 50 | } 51 | render() { 52 | const {myMark} = this.props 53 | return ( 54 | 55 | 56 | 60 | 65 | 66 | ); 67 | } 68 | } 69 | 70 | const styles = StyleSheet.create({ 71 | container: { 72 | flex: 1, 73 | justifyContent: 'center', 74 | alignItems: 'center', 75 | backgroundColor: '#ffffff', 76 | } 77 | }); 78 | 79 | -------------------------------------------------------------------------------- /app/components/other/me/Subscript.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/18. 3 | */ 4 | import React, { Component } from 'react'; 5 | import { 6 | StyleSheet, 7 | Text, 8 | View, 9 | ListView 10 | } from 'react-native'; 11 | 12 | import Original from '../../airticle/Original' 13 | import NewsCell from '../../news/NewsCell' 14 | import CommonNavigationBar from '../../../containers/CommonNavigationBar' 15 | export default class Subscript extends Component { 16 | // 构造 17 | constructor(props) { 18 | super(props); 19 | // 初始状态 20 | this.state = { 21 | dataSource: new ListView.DataSource({ 22 | rowHasChanged: (row1, row2) => row1 !== row2 23 | }) 24 | } 25 | } 26 | componentDidMount() { 27 | const {actions} = this.props 28 | console.log(actions) 29 | actions.getSubscript(1) 30 | } 31 | _onBack(){ 32 | this.props.navigator.pop() 33 | } 34 | renderRow(data,index){ 35 | const type = data.type 36 | if(type === 'Article' || type === 'audio' || type === 'video'){ 37 | const cell_type = type === 'Article' ? 'default':type 38 | return( 39 | 40 | ) 41 | }else if(type === 'news'){ 42 | return( 43 | 44 | ) 45 | } 46 | return() 47 | } 48 | render() { 49 | const {subscript} = this.props 50 | return ( 51 | 52 | 53 | 57 | 62 | 63 | ); 64 | } 65 | } 66 | 67 | const styles = StyleSheet.create({ 68 | container: { 69 | flex: 1, 70 | justifyContent: 'center', 71 | alignItems: 'center', 72 | backgroundColor: '#ffffff', 73 | } 74 | }); 75 | 76 | -------------------------------------------------------------------------------- /app/components/other/timeLine/TimeLineList.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/6. 3 | */ 4 | 5 | import React,{Component} from 'react' 6 | import { 7 | View, 8 | Text, 9 | ListView, 10 | StyleSheet, 11 | TouchableHighlight 12 | }from 'react-native' 13 | 14 | export default class TimeLineList extends Component { 15 | constructor(props) { 16 | super(props); 17 | // 初始状态 18 | this.state = { 19 | dataSource:new ListView.DataSource({ 20 | rowHasChanged:(row1,row2) => row1 !== row2 21 | }) 22 | }; 23 | } 24 | 25 | componentDidMount() { 26 | const {actions} = this.props 27 | actions.getTimeLineCategories() 28 | } 29 | _renderRow(data){ 30 | return( 31 | 32 | ) 33 | } 34 | _onPress(data){ 35 | const {onPress} = this.props 36 | if(onPress){ 37 | onPress(data) 38 | } 39 | } 40 | render(){ 41 | const {timeLine} = this.props 42 | return( 43 | 44 | {timeLine.list_data && } 49 | 50 | ) 51 | } 52 | } 53 | 54 | export class TimeLineListCell extends Component { 55 | 56 | _onPress(){ 57 | const {click} = this.props 58 | if(click){ 59 | click() 60 | } 61 | } 62 | render(){ 63 | const {pageInfo} = this.props 64 | return( 65 | 68 | 69 | {pageInfo.category.name} vol.{pageInfo.vol} {pageInfo.title} 70 | 71 | 72 | ) 73 | } 74 | } 75 | const styles = StyleSheet.create({ 76 | container:{ 77 | flex:1, 78 | paddingLeft:6, 79 | paddingRight:6, 80 | flexDirection:'row', 81 | backgroundColor:'#f4f4f4' 82 | }, 83 | cell:{ 84 | paddingLeft:16, 85 | paddingRight:16, 86 | height:80, 87 | backgroundColor:'#ffffff', 88 | borderBottomColor:'#c8c8c8', 89 | borderBottomWidth:0.5, 90 | justifyContent:'center' 91 | }, 92 | title:{ 93 | 94 | } 95 | }) 96 | -------------------------------------------------------------------------------- /app/components/other/timeLine/TimeLinePanel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/1. 3 | */ 4 | import React,{Component} from 'react' 5 | import { 6 | View, 7 | Text, 8 | Image, 9 | StyleSheet, 10 | TouchableHighlight, 11 | UIManager, 12 | findNodeHandle, 13 | InteractionManager, 14 | Platform, 15 | LayoutAnimation 16 | }from 'react-native' 17 | import MyIcon from '../../other/custom/MyIcon' 18 | export default class TimeLinePanel extends Component { 19 | // 构造 20 | constructor(props) { 21 | super(props); 22 | this.didUpdate = false 23 | if (Platform.OS === 'android') { 24 | UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true); 25 | } 26 | } 27 | getTime(timestamp){ 28 | var hour = Math.floor(timestamp/60) 29 | var sec = timestamp - (hour * 60) 30 | sec = (Array(2).join(0)+sec).slice(-2) 31 | return hour + ":" + sec 32 | } 33 | _getLinkView(quote_href){ 34 | console.log(quote_href) 35 | if(quote_href.length == 0){ 36 | return(no link) 37 | }else { 38 | return( ) 39 | } 40 | } 41 | _listen(){ 42 | const {changeProgress} = this.props 43 | if(changeProgress){ 44 | changeProgress() 45 | } 46 | } 47 | 48 | componentDidMount() { 49 | const {shouldScroll,timeLineInfo} = this.props 50 | if(timeLineInfo){ 51 | if(!this.didUpdate){ 52 | this.didUpdate = true 53 | this.timer = setTimeout(//5s 后再获取坐标 否在在播放本地音频时 在该处还没有布局好 54 | () => { 55 | var hand = findNodeHandle(this) 56 | UIManager.measure(hand,(x,y,w,h,px,py)=>{ 57 | console.log('x: '+x +' y:' + y ) 58 | if(shouldScroll){ 59 | shouldScroll(y) 60 | } 61 | }) 62 | }, 63 | 5000 64 | ); 65 | 66 | } 67 | } 68 | } 69 | componentWillUnmount() { 70 | this.timer && clearTimeout(this.timer); 71 | } 72 | 73 | render(){ 74 | const {timeLineInfo} = this.props 75 | 76 | return( 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | {this.getTime(timeLineInfo.at)} 86 | {timeLineInfo.title} 87 | 88 | {timeLineInfo.content} 89 | 90 | {timeLineInfo.quote_href.length === 0 ? 91 | (no link): 92 | () 93 | } 94 | 95 | 96 | 97 | 98 | 99 | ) 100 | } 101 | } 102 | const styles = StyleSheet.create({ 103 | container:{ 104 | flex:1, 105 | paddingLeft:6, 106 | paddingRight:6, 107 | flexDirection:'row', 108 | backgroundColor:'#f4f4f4' 109 | }, 110 | leftLineView:{ 111 | width:20, 112 | alignItems:'center' 113 | }, 114 | Line:{ 115 | flex:1, 116 | width:0.5, 117 | backgroundColor:'#444444' 118 | }, 119 | redDot:{ 120 | marginTop:10, 121 | width:10, 122 | height:10, 123 | borderRadius:5, 124 | backgroundColor:'red', 125 | position:'absolute' 126 | }, 127 | rightContentView:{ 128 | flex:1, 129 | padding:8, 130 | marginTop:8, 131 | backgroundColor:'#ffffff' 132 | }, 133 | timestamp:{ 134 | color:'#666666' 135 | }, 136 | title:{ 137 | margin:10, 138 | fontSize:15 139 | }, 140 | corver:{ 141 | height:180 142 | }, 143 | content:{ 144 | margin:6, 145 | fontSize:12, 146 | color:'#777777', 147 | lineHeight:22 148 | }, 149 | bottomContainer:{ 150 | flex:1, 151 | flexDirection:'row', 152 | justifyContent:'space-around', 153 | paddingTop:30, 154 | alignItems:'center', 155 | paddingBottom:30, 156 | 157 | }, 158 | tagImage:{ 159 | width:60 160 | } 161 | }) 162 | -------------------------------------------------------------------------------- /app/components/radio/Radio.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/10. 3 | */ 4 | import React, { Component } from 'react'; 5 | import { 6 | StyleSheet, 7 | Text, 8 | View, 9 | ListView, 10 | RefreshControl, 11 | ActivityIndicator, 12 | Platform 13 | } from 'react-native'; 14 | import Original from '../airticle/Original' 15 | import Common from '../../common/constants' 16 | export default class Radio extends Component { 17 | // 构造 18 | constructor(props) { 19 | super(props); 20 | // 初始状态 21 | this.state = { 22 | dataSource: new ListView.DataSource({ 23 | rowHasChanged: (row1, row2) => row1 !== row2 24 | }) 25 | } 26 | this.page = 1 27 | } 28 | componentDidMount() { 29 | const {actions} = this.props 30 | actions.getRadio() 31 | } 32 | 33 | renderRow(data,index){ 34 | return() 35 | } 36 | _onRefresh(){ 37 | const {actions} = this.props 38 | this.page = 1 39 | console.log('正在刷新') 40 | actions.getRadio(this.page) 41 | } 42 | _onScrollEndDrag(event){ 43 | const {contentOffset, layoutMeasurement, contentSize} = event.nativeEvent; 44 | let contentSizeH = contentSize.height; 45 | //layoutMeasurement.height 是listView的高度(小于 window.height) 46 | let viewBottomY = contentOffset.y + layoutMeasurement.height; 47 | 48 | console.log(viewBottomY - contentSizeH) 49 | if((viewBottomY - contentSizeH)>=40|| (Platform.OS === 'android' && parseInt(viewBottomY - contentSizeH) === 0)){ 50 | const {radio,actions} = this.props 51 | if(radio.isLoadMore){ 52 | return 53 | } 54 | this.page++; 55 | actions.getRadio(this.page ) 56 | } 57 | } 58 | render() { 59 | const {radio} = this.props 60 | const refreshWord = radio.isLoading ? '正在刷新':'下拉刷新' 61 | return ( 62 | 63 | 64 | 77 | } 78 | /> 79 | {radio.isLoadMore && 80 | 81 | 82 | 正在加载更多的数据... 83 | 84 | } 85 | 86 | ); 87 | } 88 | } 89 | 90 | const styles = StyleSheet.create({ 91 | container: { 92 | flex: 1, 93 | justifyContent: 'center', 94 | alignItems: 'center', 95 | backgroundColor: '#ffffff', 96 | }, 97 | welcome: { 98 | fontSize: 20, 99 | textAlign: 'center', 100 | margin: 10, 101 | }, 102 | instructions: { 103 | textAlign: 'center', 104 | color: '#333333', 105 | marginBottom: 5, 106 | }, 107 | loadingContainer: { 108 | height:30, 109 | width:Common.WINDOW.width, 110 | justifyContent: 'center', 111 | alignItems: 'center', 112 | flexDirection: 'row' 113 | } 114 | }); 115 | 116 | -------------------------------------------------------------------------------- /app/components/video/Video.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/10. 3 | */ 4 | 5 | import React, { Component } from 'react'; 6 | import { 7 | StyleSheet, 8 | Text, 9 | View, 10 | ListView, 11 | RefreshControl, 12 | ActivityIndicator, 13 | Platform 14 | } from 'react-native'; 15 | import Original from '../airticle/Original' 16 | import Common from '../../common/constants' 17 | export default class Video extends Component { 18 | // 构造 19 | constructor(props) { 20 | super(props); 21 | // 初始状态 22 | this.state = { 23 | dataSource: new ListView.DataSource({ 24 | rowHasChanged: (row1, row2) => row1 !== row2 25 | }) 26 | } 27 | this.page = 1 28 | } 29 | componentDidMount() { 30 | const {actions} = this.props 31 | actions.getVideo() 32 | } 33 | 34 | renderRow(data,index){ 35 | return() 36 | } 37 | _onRefresh(){ 38 | const {actions} = this.props 39 | this.page = 1 40 | console.log('正在刷新') 41 | actions.getVideo(this.page) 42 | } 43 | _onScrollEndDrag(event){ 44 | const {contentOffset, layoutMeasurement, contentSize} = event.nativeEvent; 45 | let contentSizeH = contentSize.height; 46 | //layoutMeasurement.height 是listView的高度(小于 window.height) 47 | let viewBottomY = contentOffset.y + layoutMeasurement.height; 48 | 49 | console.log(viewBottomY - contentSizeH) 50 | if((viewBottomY - contentSizeH)>=40|| (Platform.OS === 'android' && parseInt(viewBottomY - contentSizeH) === 0)){ 51 | const {video,actions} = this.props 52 | if(video.isLoadMore){ 53 | return 54 | } 55 | this.page++; 56 | actions.getVideo(this.page ) 57 | } 58 | } 59 | render() { 60 | const {video} = this.props 61 | const refreshWord = video.isLoading ? '正在刷新':'下拉刷新' 62 | return ( 63 | 64 | 65 | 79 | } 80 | /> 81 | {video.isLoadMore && 82 | 83 | 84 | 正在加载更多的数据... 85 | 86 | } 87 | 88 | ); 89 | } 90 | } 91 | 92 | const styles = StyleSheet.create({ 93 | container: { 94 | flex: 1, 95 | justifyContent: 'center', 96 | alignItems: 'center', 97 | backgroundColor: '#ffffff', 98 | }, 99 | welcome: { 100 | fontSize: 20, 101 | textAlign: 'center', 102 | margin: 10, 103 | }, 104 | instructions: { 105 | textAlign: 'center', 106 | color: '#333333', 107 | marginBottom: 5, 108 | }, 109 | }); 110 | 111 | -------------------------------------------------------------------------------- /app/containers/BanarNavigationBar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by leon on 2017/4/6. 3 | */ 4 | 5 | import React,{Component} from 'react' 6 | import { 7 | View, 8 | Text, 9 | Image, 10 | StyleSheet, 11 | TouchableHighlight, 12 | Animated, 13 | Button 14 | }from 'react-native' 15 | import Common from '../common/constants' 16 | import * as WeChat from 'react-native-wechat' 17 | export default class BanarNavigationBar extends Component{ 18 | // 构造 19 | constructor(props) { 20 | super(props); 21 | // 初始状态 22 | this.state = { 23 | alpha:new Animated.Value(0.8) 24 | }; 25 | } 26 | 27 | componentWillReceiveProps(props) { 28 | const {alpha} = props 29 | this.state.alpha.setValue(alpha) 30 | 31 | } 32 | _back() { 33 | const {navigator} = this.props 34 | if (navigator) { 35 | navigator.pop() 36 | } 37 | } 38 | _gotoComment(){ 39 | const {gotoComment} = this.props 40 | if (gotoComment) { 41 | gotoComment() 42 | } 43 | } 44 | _share(){ 45 | try { 46 | let result = WeChat.shareToTimeline({ 47 | type: 'text', 48 | description: '为了打动你来机核。我们把她请来了 '+ this.props.url 49 | }); 50 | } catch (e) { 51 | console.error('share text message to time line failed with:', e); 52 | } 53 | } 54 | render(){ 55 | const {likes_num} = this.props 56 | 57 | return( 58 | 59 | 63 | 64 | 65 | 返回 66 | 67 | 68 | 69 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | {likes_num} 81 | 82 | 83 | 84 | 85 | 86 | 87 | ) 88 | } 89 | } 90 | 91 | const styles = StyleSheet.create({ 92 | container:{ 93 | // position:'absolute', 94 | top: 0, 95 | left: 0, 96 | right: 0, 97 | height:50, 98 | flexDirection:'row', 99 | justifyContent:'space-between', 100 | backgroundColor:'transparent', 101 | borderBottomColor: '#d9d9d9', 102 | alignItems:'center', 103 | position:'absolute', 104 | padding:10 105 | }, 106 | ToolView:{ 107 | flexDirection:'row', 108 | justifyContent:'space-around', 109 | alignItems:'center', 110 | paddingRight:26 111 | }, 112 | icon:{ 113 | marginLeft:20, 114 | tintColor:'white' 115 | }, 116 | likeText:{ 117 | color:'#c8c8c8', 118 | fontSize:10, 119 | marginLeft:4 120 | }, 121 | backIcon:{ 122 | height:30, 123 | tintColor:'white' 124 | }, 125 | backContainer:{ 126 | flexDirection:'row', 127 | alignItems:'center' 128 | }, 129 | text:{ 130 | fontSize:17, 131 | color:'#fff', 132 | marginLeft:5 133 | } 134 | }) -------------------------------------------------------------------------------- /app/containers/CommentNavigationBar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/3/27. 3 | */ 4 | import React,{Component} from 'react' 5 | import { 6 | View, 7 | Text, 8 | Image, 9 | StyleSheet, 10 | TouchableHighlight, 11 | Animated, 12 | Button, 13 | StatusBar 14 | }from 'react-native' 15 | import Common from '../common/constants' 16 | import SegmentedControl from '../components/custom/SegmentedControl' 17 | export default class CommentNavigationBar extends Component{ 18 | 19 | _back(){ 20 | const {onBack} = this.props 21 | if(onBack){ 22 | onBack() 23 | } 24 | } 25 | _gotoComment(){ 26 | const {gotoComment} = this.props 27 | if(gotoComment){ 28 | gotoComment() 29 | } 30 | } 31 | render(){ 32 | const {segmentDidSelectIndex,object} = this.props 33 | return( 34 | 35 | 64 | ) 65 | } 66 | } 67 | 68 | const styles = StyleSheet.create({ 69 | container:{ 70 | // position:'absolute', 71 | top: 0, 72 | left: 0, 73 | right: 0, 74 | height:64, 75 | flexDirection:'row', 76 | justifyContent:'space-between', 77 | backgroundColor:'white', 78 | borderBottomWidth:Common.WINDOW.onePR, 79 | borderBottomColor: '#d9d9d9', 80 | alignItems:'center', 81 | paddingTop:20, 82 | paddingLeft:10, 83 | paddingRight:10 84 | }, 85 | backIcon:{ 86 | height:30, 87 | 88 | }, 89 | backContainer:{ 90 | flexDirection:'row', 91 | alignItems:'center', 92 | width:80, 93 | alignSelf:'center' 94 | }, 95 | text:{ 96 | fontSize:15, 97 | color:'#666666', 98 | marginLeft:4 99 | } 100 | }) -------------------------------------------------------------------------------- /app/containers/CommonNavigationBar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/3/27. 3 | */ 4 | import React,{Component} from 'react' 5 | import { 6 | View, 7 | Text, 8 | Image, 9 | StyleSheet, 10 | TouchableHighlight, 11 | StatusBar 12 | }from 'react-native' 13 | import Common from '../common/constants' 14 | 15 | export default class CommonNavigationBar extends Component{ 16 | 17 | _back(){ 18 | const {onBack} = this.props 19 | if(onBack){ 20 | onBack() 21 | } 22 | } 23 | _rightClick(){ 24 | const {rightClick} = this.props 25 | if(rightClick){ 26 | rightClick() 27 | } 28 | } 29 | render(){ 30 | const {backTitle,title,rightTitle} = this.props 31 | const leftTitle = backTitle ? backTitle:'返回' 32 | return( 33 | 34 | 59 | ) 60 | } 61 | } 62 | 63 | const styles = StyleSheet.create({ 64 | container:{ 65 | width:Common.WINDOW.width, 66 | height:64, 67 | flexDirection:'row', 68 | backgroundColor:'white', 69 | borderBottomWidth:Common.WINDOW.onePR, 70 | borderBottomColor: '#d9d9d9', 71 | alignItems:'center', 72 | paddingTop:20, 73 | paddingLeft:10, 74 | paddingRight:10, 75 | justifyContent:'space-between' 76 | }, 77 | backIcon:{ 78 | height:30, 79 | 80 | }, 81 | backContainer:{ 82 | flexDirection:'row', 83 | alignItems:'center', 84 | }, 85 | text:{ 86 | fontSize:15, 87 | color:'#666666', 88 | marginLeft:4 89 | }, 90 | title:{ 91 | fontSize:17, 92 | color:'#666666', 93 | alignSelf:'center', 94 | position:'absolute', 95 | left:(Common.WINDOW.width-200)/2, 96 | right:(Common.WINDOW.width-200)/2, 97 | paddingTop:20, 98 | textAlign:'center', 99 | width:200 100 | } 101 | 102 | }) 103 | -------------------------------------------------------------------------------- /app/containers/ControllerTabBar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/10. 3 | */ 4 | 5 | import React, {Component} from 'react'; 6 | import { 7 | StyleSheet, 8 | View, 9 | Text, 10 | TouchableOpacity, 11 | Image, 12 | LayoutAnimation, 13 | ScrollView, 14 | Animated, 15 | Easing 16 | } from 'react-native'; 17 | import Constants from '../common/constants'; 18 | 19 | const IndicatorAnimation = { 20 | duration: 100, 21 | create: { 22 | type: LayoutAnimation.Types.linear, 23 | property: LayoutAnimation.Properties.left 24 | }, 25 | update: { 26 | type: LayoutAnimation.Types.easeInEaseOut 27 | } 28 | } 29 | 30 | export default class ControllerTabBar extends Component { 31 | static propType = { 32 | goToPage: React.PropTypes.func, 33 | activeTab: React.PropTypes.number, 34 | tabs: React.PropTypes.array, 35 | 36 | tabNames: React.PropTypes.array 37 | }; 38 | 39 | constructor(props) { 40 | super(props); 41 | 42 | this.state = { 43 | indicatorPosition: 0, 44 | translateValue: new Animated.Value(0), 45 | activeTab:0 46 | } 47 | } 48 | _onMomentumScrollEnd(event){ 49 | const offset = { ...event.nativeEvent.contentOffset }; 50 | var page = Math.floor(offset.x/(Constants.WINDOW.width/3)) 51 | this._goToPage(page + 1); 52 | } 53 | 54 | setupIndicatorValue(index){ 55 | var value = 0.5 56 | 57 | switch (index){ 58 | case 0: 59 | value = 0 60 | break; 61 | case this.props.tabs.length - 1: 62 | value = 1 63 | break; 64 | default: 65 | value = 0.5 66 | break; 67 | } 68 | // console.log('page = ' + index +'value = ' + value) 69 | Animated.timing(this.state.translateValue, 70 | {toValue:value, 71 | duration:200, 72 | easing: Easing.out(Easing.linear),//线性变化,匀速旋转 73 | isInteraction: false,//加入此参数可解决阻塞InteractionManager.runAfterInteractions,官方文档上无此参数说明 74 | } 75 | ).start() 76 | } 77 | 78 | _goToPage(index){ 79 | this.props.goToPage(index); 80 | this.setupPageUI(index) 81 | } 82 | 83 | setupPageUI(index){ 84 | this.setupIndicatorValue(index) 85 | this.setState({ 86 | activeTab:index 87 | }) 88 | var seq = 0 89 | const len = this.props.tabNames.length 90 | if(index - 1 > 0 && index < len-1){ 91 | seq = index - 1 92 | const offset = (Constants.WINDOW.width/3) * seq 93 | this.scrollView.scrollTo({ y: 0, x: offset, animated:true }) 94 | }else if(index- 1 <= 0){ 95 | this.scrollView.scrollTo({ y: 0, x: 0, animated:true }) 96 | }else if(index === len-1){ 97 | const offset = (Constants.WINDOW.width/3) * (index - 2) 98 | this.scrollView.scrollTo({ y: 0, x: offset, animated:true }) 99 | } 100 | } 101 | render() { 102 | return ( 103 | 104 | {this.scrollView = c;}} 106 | style={styles.scroll} 107 | horizontal={true} 108 | showsHorizontalScrollIndicator={false} 109 | pagingEnabled={true} 110 | onScrollEndDrag ={this._onMomentumScrollEnd.bind(this)} 111 | scrollEventThrottle={200} 112 | bounces={false} 113 | 114 | > 115 | {this.props.tabs.map((tab, i) => { 116 | let color = this.state.activeTab === i ? 'red' : 'black'; 117 | return ( 118 | 124 | 125 | {this.props.tabNames[i]} 126 | 127 | 128 | ) 129 | })} 130 | 131 | 132 | 140 | 141 | ) 142 | } 143 | } 144 | 145 | const styles = StyleSheet.create({ 146 | container: { 147 | height:36, 148 | width:Constants.WINDOW.width, 149 | }, 150 | scroll: { 151 | flex:1 152 | }, 153 | title: { 154 | flex:1, 155 | width: Constants.WINDOW.width/3, 156 | justifyContent:'center', 157 | alignItems:'center', 158 | height:36, 159 | width:Constants.WINDOW.width/3 160 | }, 161 | 162 | indicator: { 163 | backgroundColor: 'red', 164 | height: 3, 165 | width: 50, 166 | borderRadius: 1.5, 167 | position:'absolute', 168 | bottom:0, 169 | // left: ( Constants.WINDOW.width - 50)/2, 170 | 171 | } 172 | }); -------------------------------------------------------------------------------- /app/containers/MenuContainer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by leon on 2017/4/15. 3 | */ 4 | import React, { Component } from 'react'; 5 | import { 6 | View, 7 | Text, 8 | Button, 9 | StyleSheet, 10 | Image, 11 | ScrollView, 12 | TouchableHighlight 13 | } from 'react-native'; 14 | 15 | const items = ['订阅', '消息', '收藏','下载','投稿'] 16 | 17 | export default class ControlPanel extends Component { 18 | 19 | _onSelectItem(title){ 20 | const {selectRow} = this.props 21 | if(selectRow){ 22 | selectRow(title) 23 | } 24 | } 25 | 26 | render() { 27 | const {actions,application} = this.props 28 | // console.log(application.user) 29 | const avatar = application.user ? {uri:application.user.thumb_url}:require('../resource/default-avatar~iphone.png') 30 | return ( 31 | 32 | 33 | 37 | 40 | 41 | 42 | { 43 | application.user ?{application.user.nickname}: 44 | 未登录 45 | } 46 | 47 | 51 | {items.map((title,index)=>{ 52 | return( 53 | 59 | {title} 60 | ) 61 | }) 62 | } 63 | 64 | 65 | ) 66 | } 67 | } 68 | const styles = StyleSheet.create({ 69 | container:{ 70 | flex:1, 71 | backgroundColor:'#fff', 72 | alignItems:'center', 73 | padding:40 74 | }, 75 | avatarContainer:{ 76 | alignItems:'center', 77 | borderBottomColor:'#999999', 78 | borderBottomWidth:0.5, 79 | paddingBottom:50 80 | }, 81 | avatar:{ 82 | width:80, 83 | height:80, 84 | borderRadius:40 85 | }, 86 | nickname:{ 87 | marginTop:10 88 | }, 89 | scrollContainer:{ 90 | width:120, 91 | height:200 92 | }, 93 | items:{ 94 | width:120, 95 | padding:20, 96 | alignItems:'center' 97 | }, 98 | title:{ 99 | color:'#666666', 100 | fontSize:18 101 | } 102 | }) -------------------------------------------------------------------------------- /app/containers/TabBar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by ljunb on 16/8/21. 3 | */ 4 | import React, { Component } from 'react'; 5 | import { 6 | StyleSheet, 7 | View, 8 | Text, 9 | TouchableOpacity, 10 | Image, 11 | } from 'react-native'; 12 | 13 | export default class TabBar extends Component { 14 | static propType = { 15 | goToPage : React.PropTypes.func, 16 | activeTab : React.PropTypes.number, 17 | tabs : React.PropTypes.array, 18 | 19 | tabNames : React.PropTypes.array, 20 | tabIconNames: React.PropTypes.array 21 | }; 22 | 23 | componentDidMount() { 24 | this.props.scrollValue.addListener(this.setAnimationValue); 25 | } 26 | 27 | setAnimationValue({value}) { 28 | console.log(value); 29 | } 30 | 31 | render() { 32 | return ( 33 | 34 | {this.props.tabs.map((tab, i) => { 35 | let color = this.props.activeTab === i ? 'red' : 'gray'; 36 | let icon = this.props.activeTab == i ? this.props.selectedTabIconNames[i] : this.props.tabIconNames[i]; 37 | return ( 38 | this.props.goToPage(i)} 43 | > 44 | 45 | 49 | 50 | {this.props.tabNames[i]} 51 | 52 | 53 | 54 | ) 55 | })} 56 | 57 | ) 58 | } 59 | } 60 | 61 | const styles = StyleSheet.create({ 62 | tabs: { 63 | flexDirection: 'row', 64 | height: 49, 65 | borderTopColor: '#d9d9d9', 66 | }, 67 | 68 | tab: { 69 | flex: 1, 70 | justifyContent: 'center', 71 | alignItems: 'center', 72 | }, 73 | 74 | tabItem: { 75 | flexDirection: 'column', 76 | alignItems: 'center', 77 | justifyContent: 'space-around' 78 | }, 79 | 80 | icon: { 81 | width: 26, 82 | height: 26, 83 | marginBottom: 2 84 | } 85 | }) -------------------------------------------------------------------------------- /app/reducers/application.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import createReducer from '../utils/create-reducer' 3 | import Commom from '../common/constants' 4 | const initialState = { 5 | tab:'home', 6 | user:null 7 | } 8 | 9 | const actionHandle = { 10 | [Commom.APP.TAB]:(state,action) => { 11 | tab:action.data 12 | }, 13 | [Commom.APP.NAVIGATION]: (state, action) => { 14 | return Object.assign({}, state, { 15 | navigator: action.data 16 | }) 17 | }, 18 | [Commom.APP.SIGNIN]: (state, action) => { 19 | return Object.assign({}, state, { 20 | user: action.user 21 | }) 22 | }, 23 | [Commom.APP.SIGNOUT]: (state, action) => { 24 | return Object.assign({}, state, { 25 | user: action.user 26 | }) 27 | } 28 | } 29 | 30 | export default createReducer(initialState,actionHandle) -------------------------------------------------------------------------------- /app/reducers/article.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/3/22. 3 | */ 4 | import createReducer from '../utils/create-reducer' 5 | import Commom from '../common/constants' 6 | const initialState = { 7 | data: [], 8 | isLoading:false, 9 | isLoadMore:false, 10 | } 11 | 12 | const actionHandler = { 13 | [Commom.ARTICLE.INFO]: (state, action) => { 14 | 15 | //加载状态 16 | if(action.isLoading || action.isLoadMore){ 17 | return Object.assign({}, state, { 18 | isLoading:action.isLoading, 19 | isLoadMore:action.isLoadMore 20 | }) 21 | } 22 | 23 | //加载完成状态 24 | let airticle = null; 25 | if(action.page !== 1){ 26 | airticle = state.data.concat(action.data) 27 | }else { 28 | airticle = action.data 29 | } 30 | return Object.assign({}, state, { 31 | data: airticle, 32 | isLoading:false, 33 | isLoadMore:false 34 | }) 35 | 36 | }, 37 | 38 | [Commom.ARTICLE.DETAIL]: (state, action) => { 39 | return Object.assign({}, state, { 40 | data: action.data 41 | }) 42 | } 43 | } 44 | 45 | export default createReducer(initialState, actionHandler) -------------------------------------------------------------------------------- /app/reducers/bannar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/3/22. 3 | */ 4 | import createReducer from '../utils/create-reducer' 5 | import Common from '../common/constants' 6 | const initialState = { 7 | data: [] 8 | } 9 | 10 | const actionHandler = { 11 | [Common.HOME.BANNAR]: (state, action) => { 12 | return Object.assign({}, state, { 13 | data: action.data 14 | }) 15 | }, 16 | } 17 | 18 | export default createReducer(initialState, actionHandler) 19 | -------------------------------------------------------------------------------- /app/reducers/categories.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by leon on 2017/4/17. 3 | */ 4 | import createReducer from '../utils/create-reducer' 5 | import Commom from '../common/constants' 6 | const initialState = { 7 | data: [], 8 | detail:[] 9 | } 10 | 11 | const actionHandler = { 12 | [Commom.CATEGORIES.INFO]: (state, action) => { 13 | return Object.assign({}, state, { 14 | data: action.data, 15 | }) 16 | }, 17 | [Commom.CATEGORIES.DETAIL]: (state, action) => { 18 | return Object.assign({}, state, { 19 | detail: action.data, 20 | }) 21 | }, 22 | [Commom.CATEGORIES.SUB]: (state, action) => { 23 | return Object.assign({}, state, { 24 | sub: action.data, 25 | }) 26 | }, 27 | [Commom.CATEGORIES.CLEAR]: (state, action) => { 28 | return Object.assign({}, state, { 29 | sub: null, 30 | }) 31 | } 32 | } 33 | 34 | 35 | export default createReducer(initialState, actionHandler) 36 | -------------------------------------------------------------------------------- /app/reducers/comment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/3/28. 3 | */ 4 | import createReducer from '../utils/create-reducer' 5 | import Commom from '../common/constants' 6 | const initialState = { 7 | ctype:Commom.COMMENT.HOT, 8 | data: [], 9 | isLoading:false, 10 | isLoadMore:false, 11 | } 12 | 13 | const actionHandler = { 14 | [Commom.COMMENT.HOT]: (state, action) => { 15 | //加载状态 16 | if(action.isLoading || action.isLoadMore){ 17 | return Object.assign({}, state, { 18 | isLoading:action.isLoading, 19 | isLoadMore:action.isLoadMore, 20 | 21 | }) 22 | } 23 | 24 | //加载完成状态 25 | let comment = null; 26 | if(action.page !== 1){ 27 | comment = state.data.concat(action.data) 28 | }else { 29 | comment = action.data 30 | } 31 | return Object.assign({}, state, { 32 | type:Commom.COMMENT.HOT, 33 | data: comment, 34 | isLoading:false, 35 | isLoadMore:false 36 | }) 37 | 38 | }, 39 | 40 | [Commom.COMMENT.TIME]: (state, action) => { 41 | //加载状态 42 | if(action.isLoading || action.isLoadMore){ 43 | return Object.assign({}, state, { 44 | isLoading:action.isLoading, 45 | isLoadMore:action.isLoadMore 46 | }) 47 | } 48 | 49 | //加载完成状态 50 | let comment = null; 51 | if(action.page !== 1){ 52 | comment = state.data.concat(action.data) 53 | }else { 54 | comment = action.data 55 | } 56 | return Object.assign({}, state, { 57 | type:Commom.COMMENT.TIME, 58 | data: comment, 59 | isLoading:false, 60 | isLoadMore:false 61 | }) 62 | } 63 | } 64 | 65 | export default createReducer(initialState, actionHandler) -------------------------------------------------------------------------------- /app/reducers/download.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by leon on 2017/5/6. 3 | */ 4 | import createReducer from '../utils/create-reducer' 5 | import Commom from '../common/constants' 6 | const initialState = { 7 | data:null, 8 | type:'undownloding' 9 | } 10 | const actionHandle = { 11 | 12 | [Commom.DOWNLOAD.BEGIN]:(state,action) => { 13 | console.log(action) 14 | return Object.assign({}, state, { 15 | data:action.data, 16 | }) 17 | }, 18 | [Commom.DOWNLOAD.END]:(state,action) => { 19 | return Object.assign({}, state, { 20 | data:action.data 21 | }) 22 | } 23 | } 24 | 25 | export default createReducer(initialState,actionHandle) -------------------------------------------------------------------------------- /app/reducers/home.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/3/22. 3 | */ 4 | import createReducer from '../utils/create-reducer' 5 | import Commom from '../common/constants' 6 | const initialState = { 7 | data: [], 8 | isLoading:false, 9 | isLoadMore:false 10 | } 11 | 12 | const actionHandler = { 13 | [Commom.HOME.INFO]: (state, action) => { 14 | 15 | //加载状态 16 | if(action.isLoading || action.isLoadMore){ 17 | console.log('return 状态') 18 | return Object.assign({}, state, { 19 | isLoading:action.isLoading, 20 | isLoadMore:action.isLoadMore 21 | }) 22 | } 23 | 24 | //加载完成状态 25 | let home = null; 26 | if(action.page !== 1){ 27 | home = state.data.concat(action.data) 28 | }else { 29 | home = action.data 30 | } 31 | return Object.assign({}, state, { 32 | data: home, 33 | isLoading:false, 34 | isLoadMore:false 35 | }) 36 | }, 37 | 38 | [Commom.HOME.DETAIL]: (state, action) => { 39 | return Object.assign({}, state, { 40 | data: action.data 41 | }) 42 | } 43 | } 44 | 45 | export default createReducer(initialState, actionHandler) -------------------------------------------------------------------------------- /app/reducers/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/3/20. 3 | */ 4 | import { combineReducers } from 'redux' 5 | 6 | import application from '../reducers/application' 7 | import homeInfo from '../reducers/home' 8 | import bannar from '../reducers/bannar' 9 | import news from '../reducers/news' 10 | import article from '../reducers/article' 11 | import comment from '../reducers/comment' 12 | import pageInfo from '../reducers/pageInfo' 13 | import timeLine from '../reducers/timeLine' 14 | import play from '../reducers/play' 15 | import radio from '../reducers/radio' 16 | import video from '../reducers/video' 17 | import categories from '../reducers/categories' 18 | import subscript from '../reducers/subscript' 19 | import myMark from '../reducers/myMark' 20 | import download from '../reducers/download' 21 | const reducers = combineReducers({ 22 | application, 23 | homeInfo, 24 | bannar, 25 | news, 26 | article, 27 | comment, 28 | pageInfo, 29 | timeLine, 30 | play, 31 | radio, 32 | video, 33 | categories, 34 | subscript, 35 | myMark, 36 | download 37 | }); 38 | 39 | export default reducers -------------------------------------------------------------------------------- /app/reducers/myMark.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/18. 3 | */ 4 | import createReducer from '../utils/create-reducer' 5 | import Commom from '../common/constants' 6 | const initialState = { 7 | data: [] 8 | } 9 | 10 | const actionHandler = { 11 | [Commom.MYMARK.INFO]: (state, action) => { 12 | return Object.assign({}, state, { 13 | data: action.data 14 | }) 15 | } 16 | } 17 | 18 | export default createReducer(initialState, actionHandler) -------------------------------------------------------------------------------- /app/reducers/news.js: -------------------------------------------------------------------------------- 1 | import createReducer from '../utils/create-reducer' 2 | import Commom from '../common/constants' 3 | const initialState = { 4 | data: [], 5 | isLoading:false, 6 | isLoadMore:false, 7 | } 8 | 9 | const actionHandler = { 10 | [Commom.NEWS.INFO]: (state, action) => { 11 | //加载状态 12 | if(action.isLoading || action.isLoadMore){ 13 | return Object.assign({}, state, { 14 | isLoading:action.isLoading, 15 | isLoadMore:action.isLoadMore 16 | }) 17 | } 18 | 19 | //加载完成状态 20 | let news = null; 21 | if(action.page !== 1){ 22 | news = state.data.concat(action.data) 23 | }else { 24 | news = action.data 25 | } 26 | return Object.assign({}, state, { 27 | data: news, 28 | isLoading:false, 29 | isLoadMore:false 30 | }) 31 | }, 32 | 33 | [Commom.NEWS.DETAIL]: (state, action) => { 34 | return Object.assign({}, state, { 35 | data: action.data 36 | }) 37 | } 38 | } 39 | 40 | export default createReducer(initialState, actionHandler) 41 | -------------------------------------------------------------------------------- /app/reducers/pageInfo.js: -------------------------------------------------------------------------------- 1 | import createReducer from '../utils/create-reducer' 2 | import Commom from '../common/constants' 3 | const initialState = { 4 | data: [] 5 | } 6 | 7 | const actionHandler = { 8 | [Commom.PAGEINFO.INFO]: (state, action) => { 9 | return Object.assign({}, state, { 10 | data: action.data, 11 | type:action.type 12 | }) 13 | } 14 | } 15 | 16 | export default createReducer(initialState, actionHandler) 17 | -------------------------------------------------------------------------------- /app/reducers/play.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by leon on 2017/4/8. 3 | */ 4 | import createReducer from '../utils/create-reducer' 5 | import Commom from '../common/constants' 6 | const initialState = { 7 | show:false, 8 | pageInfo:null, 9 | isPlay:false 10 | } 11 | 12 | const actionHandle = { 13 | [Commom.PLAY.SHOW]:(state,action) => { 14 | return Object.assign({}, state, { 15 | id:action.id, 16 | pageInfo:action.pageInfo, 17 | show:true 18 | }) 19 | }, 20 | [Commom.PLAY.HIDDEN]: (state, action) => { 21 | return Object.assign({}, state, { 22 | id:action.id, 23 | show:false 24 | }) 25 | }, 26 | [Commom.PLAY.PLAY]: (state, action) => { 27 | return Object.assign({}, state, { 28 | isPlay:action.isPlay 29 | }) 30 | } 31 | } 32 | 33 | export default createReducer(initialState,actionHandle) -------------------------------------------------------------------------------- /app/reducers/radio.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/10. 3 | */ 4 | import createReducer from '../utils/create-reducer' 5 | import Commom from '../common/constants' 6 | const initialState = { 7 | data: [], 8 | isLoading:false, 9 | isLoadMore:false 10 | } 11 | 12 | const actionHandler = { 13 | [Commom.RADIO.INFO]: (state, action) => { 14 | //加载状态 15 | if(action.isLoading || action.isLoadMore){ 16 | console.log('return 状态') 17 | return Object.assign({}, state, { 18 | isLoading:action.isLoading, 19 | isLoadMore:action.isLoadMore 20 | }) 21 | } 22 | 23 | //加载完成状态 24 | let radio = null; 25 | if(action.page !== 1){ 26 | radio = state.data.concat(action.data) 27 | }else { 28 | radio = action.data 29 | } 30 | return Object.assign({}, state, { 31 | data: radio, 32 | isLoading:false, 33 | isLoadMore:false 34 | }) 35 | } 36 | } 37 | 38 | export default createReducer(initialState, actionHandler) 39 | -------------------------------------------------------------------------------- /app/reducers/subscript.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/18. 3 | */ 4 | import createReducer from '../utils/create-reducer' 5 | import Commom from '../common/constants' 6 | const initialState = { 7 | data: [], 8 | count:0 9 | } 10 | 11 | const actionHandler = { 12 | [Commom.SUBSCRIPT.INFO]: (state, action) => { 13 | return Object.assign({}, state, { 14 | data: action.data.originals, 15 | count:action.data.count, 16 | }) 17 | } 18 | } 19 | 20 | export default createReducer(initialState, actionHandler) -------------------------------------------------------------------------------- /app/reducers/timeLine.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/1. 3 | */ 4 | import createReducer from '../utils/create-reducer' 5 | import Commom from '../common/constants' 6 | const initialState = { 7 | data: [] 8 | } 9 | 10 | const actionHandler = { 11 | [Commom.TIMELINE.INFO]: (state, action) => { 12 | return Object.assign({}, state, { 13 | data: action.data 14 | }) 15 | }, 16 | [Commom.TIMELINE.CATEGORY]: (state, action) => { 17 | return Object.assign({}, state, { 18 | list_data: action.data 19 | }) 20 | } 21 | } 22 | 23 | export default createReducer(initialState, actionHandler) -------------------------------------------------------------------------------- /app/reducers/video.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/4/10. 3 | */ 4 | 5 | import createReducer from '../utils/create-reducer' 6 | import Commom from '../common/constants' 7 | const initialState = { 8 | data: [], 9 | isLoading:false, 10 | isLoadMore:false, 11 | } 12 | 13 | const actionHandler = { 14 | [Commom.VIDEO.INFO]: (state, action) => { 15 | //加载状态 16 | if(action.isLoading || action.isLoadMore){ 17 | return Object.assign({}, state, { 18 | isLoading:action.isLoading, 19 | isLoadMore:action.isLoadMore 20 | }) 21 | } 22 | //加载完成状态 23 | let video = null; 24 | if(action.page !== 1){ 25 | video = state.data.concat(action.data) 26 | }else { 27 | video = action.data 28 | } 29 | return Object.assign({}, state, { 30 | data: video, 31 | isLoading:false, 32 | isLoadMore:false 33 | }) 34 | } 35 | } 36 | 37 | export default createReducer(initialState, actionHandler) 38 | -------------------------------------------------------------------------------- /app/resource/GGG.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/GGG.jpg -------------------------------------------------------------------------------- /app/resource/arrow-left~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/arrow-left~iphone.png -------------------------------------------------------------------------------- /app/resource/arrow-left~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/arrow-left~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/default-avatar~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/default-avatar~iphone.png -------------------------------------------------------------------------------- /app/resource/default-avatar~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/default-avatar~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/ic_tab_homepage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/ic_tab_homepage.png -------------------------------------------------------------------------------- /app/resource/ic_tab_homepage_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/ic_tab_homepage_select.png -------------------------------------------------------------------------------- /app/resource/ic_tab_my.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/ic_tab_my.png -------------------------------------------------------------------------------- /app/resource/ic_tab_my_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/ic_tab_my_select.png -------------------------------------------------------------------------------- /app/resource/ic_tab_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/ic_tab_search.png -------------------------------------------------------------------------------- /app/resource/ic_tab_search_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/ic_tab_search_select.png -------------------------------------------------------------------------------- /app/resource/ic_tab_shop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/ic_tab_shop.png -------------------------------------------------------------------------------- /app/resource/ic_tab_shop_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/ic_tab_shop_select.png -------------------------------------------------------------------------------- /app/resource/icon-category~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-category~iphone.png -------------------------------------------------------------------------------- /app/resource/icon-category~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-category~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/icon-close-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-close-down.png -------------------------------------------------------------------------------- /app/resource/icon-close-down@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-close-down@2x.png -------------------------------------------------------------------------------- /app/resource/icon-comment-wo~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-comment-wo~iphone.png -------------------------------------------------------------------------------- /app/resource/icon-comment-wo~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-comment-wo~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/icon-comment-w~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-comment-w~iphone.png -------------------------------------------------------------------------------- /app/resource/icon-comment-w~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-comment-w~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/icon-comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-comment.png -------------------------------------------------------------------------------- /app/resource/icon-comment@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-comment@2x.png -------------------------------------------------------------------------------- /app/resource/icon-downloaded~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-downloaded~iphone.png -------------------------------------------------------------------------------- /app/resource/icon-downloaded~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-downloaded~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/icon-download~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-download~iphone.png -------------------------------------------------------------------------------- /app/resource/icon-download~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-download~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/icon-like-r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-like-r.png -------------------------------------------------------------------------------- /app/resource/icon-like-r@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-like-r@2x.png -------------------------------------------------------------------------------- /app/resource/icon-like-w~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-like-w~iphone.png -------------------------------------------------------------------------------- /app/resource/icon-like-w~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-like-w~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/icon-like.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-like.png -------------------------------------------------------------------------------- /app/resource/icon-like@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-like@2x.png -------------------------------------------------------------------------------- /app/resource/icon-list~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-list~iphone.png -------------------------------------------------------------------------------- /app/resource/icon-list~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-list~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/icon-mark~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-mark~iphone.png -------------------------------------------------------------------------------- /app/resource/icon-mark~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-mark~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/icon-menu~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-menu~iphone.png -------------------------------------------------------------------------------- /app/resource/icon-menu~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-menu~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/icon-pause~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-pause~iphone.png -------------------------------------------------------------------------------- /app/resource/icon-pause~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-pause~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/icon-play~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-play~iphone.png -------------------------------------------------------------------------------- /app/resource/icon-play~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-play~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/icon-share~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-share~iphone.png -------------------------------------------------------------------------------- /app/resource/icon-share~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/icon-share~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/logo-big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/logo-big.png -------------------------------------------------------------------------------- /app/resource/logo-big@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/logo-big@2x.png -------------------------------------------------------------------------------- /app/resource/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/logo.png -------------------------------------------------------------------------------- /app/resource/logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/logo@2x.png -------------------------------------------------------------------------------- /app/resource/navigationbar_back@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/navigationbar_back@2x.png -------------------------------------------------------------------------------- /app/resource/navigationbar_back@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/navigationbar_back@3x.png -------------------------------------------------------------------------------- /app/resource/photo~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/photo~iphone.png -------------------------------------------------------------------------------- /app/resource/photo~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/photo~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/player-audio~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/player-audio~iphone.png -------------------------------------------------------------------------------- /app/resource/player-audio~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/player-audio~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/player-slider-handle~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/player-slider-handle~iphone.png -------------------------------------------------------------------------------- /app/resource/player-slider-handle~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/player-slider-handle~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/player-video~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/player-video~iphone.png -------------------------------------------------------------------------------- /app/resource/player-video~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/player-video~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/player-w~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/player-w~iphone.png -------------------------------------------------------------------------------- /app/resource/player-w~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/player-w~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/signin-weibo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/signin-weibo.png -------------------------------------------------------------------------------- /app/resource/signin-weibo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/signin-weibo@2x.png -------------------------------------------------------------------------------- /app/resource/signin-weixin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/signin-weixin.png -------------------------------------------------------------------------------- /app/resource/signin-weixin@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/signin-weixin@2x.png -------------------------------------------------------------------------------- /app/resource/subscript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/subscript.png -------------------------------------------------------------------------------- /app/resource/subscript@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/subscript@2x.png -------------------------------------------------------------------------------- /app/resource/timeline-listen~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/timeline-listen~iphone.png -------------------------------------------------------------------------------- /app/resource/timeline-listen~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/timeline-listen~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/timeline-source~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/timeline-source~iphone.png -------------------------------------------------------------------------------- /app/resource/timeline-source~iphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/timeline-source~iphone@2x.png -------------------------------------------------------------------------------- /app/resource/unsubscript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/unsubscript.png -------------------------------------------------------------------------------- /app/resource/unsubscript@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/app/resource/unsubscript@2x.png -------------------------------------------------------------------------------- /app/root.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon.Hwa on 17/3/20. 3 | */ 4 | import React,{Component}from 'react' 5 | 6 | import { 7 | View, 8 | Text, 9 | StyleSheet 10 | } from 'react-native' 11 | import {createStore,applyMiddleware} from 'redux' 12 | import {Provider} from 'react-redux' 13 | import thunk from 'redux-thunk'// 14 | import reducers from './reducers' 15 | import App from './containers/app' 16 | 17 | import Constants from './common/constants'; 18 | 19 | import MyStorage from './channel/MyStorage' 20 | 21 | 22 | const createStoreWithWM = applyMiddleware(thunk)(createStore) 23 | const store = createStoreWithWM(reducers) 24 | 25 | /** 26 | * 27 | * http://www.g-cores.com/api/set_device_token 28 | * auth_exclusive dpkynzs2q0wm9o5gi1r83fcabthl4eu 29 | device_token 08532edf3c771890ad23a62d65cb749f02341c6d72213eb6d72ba97e7547e580 30 | user_id -1 31 | * 32 | * */ 33 | export default class Root extends Component { 34 | 35 | render() { 36 | global.Common = Constants; 37 | let storage = new MyStorage() 38 | storage.loadAccount((user,err)=>{ 39 | 40 | }) 41 | return ( 42 | 43 | 44 | 45 | ) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/utils/create-reducer.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | export default function createReducer (initialState, actionHandlers) { 4 | return (state = initialState, action) => { 5 | const reduceFn = actionHandlers[action.type] 6 | if (!reduceFn) return state 7 | // Looks it works like Object.assign 8 | return { ...state, ...reduceFn(state, action) } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /index.android.js: -------------------------------------------------------------------------------- 1 | 2 | import {AppRegistry} from 'react-native' 3 | import Root from './app/root' 4 | 5 | AppRegistry.registerComponent('GCore', () => Root); 6 | 7 | -------------------------------------------------------------------------------- /index.ios.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | import {AppRegistry} from 'react-native' 7 | import Root from './app/root' 8 | 9 | AppRegistry.registerComponent('GCore', () => Root); 10 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | import {AppRegistry} from 'react-native' 7 | import Root from './app/root' 8 | AppRegistry.registerComponent('GCore', () => Root); 9 | AppRegistry.registerHeadlessTask('TrackPlayer', () => require('./player-handler.js')); -------------------------------------------------------------------------------- /ios/GCore-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | -------------------------------------------------------------------------------- /ios/GCore-tvOS/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 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UIViewControllerBasedStatusBarAppearance 38 | 39 | NSLocationWhenInUseUsageDescription 40 | 41 | NSAppTransportSecurity 42 | 43 | 44 | NSExceptionDomains 45 | 46 | localhost 47 | 48 | NSExceptionAllowsInsecureHTTPLoads 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /ios/GCore-tvOSTests/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 | -------------------------------------------------------------------------------- /ios/GCore.xcodeproj/xcshareddata/xcschemes/GCore-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /ios/GCore.xcodeproj/xcshareddata/xcschemes/GCore.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /ios/GCore/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 | -------------------------------------------------------------------------------- /ios/GCore/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 13 | #import 14 | 15 | @implementation AppDelegate 16 | 17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 18 | { 19 | NSURL *jsCodeLocation; 20 | 21 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 22 | 23 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 24 | moduleName:@"GCore" 25 | initialProperties:nil 26 | launchOptions:launchOptions]; 27 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 28 | 29 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 30 | UIViewController *rootViewController = [UIViewController new]; 31 | rootViewController.view = rootView; 32 | self.window.rootViewController = rootViewController; 33 | [self.window makeKeyAndVisible]; 34 | return YES; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /ios/GCore/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon1024x024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon1024x024.png -------------------------------------------------------------------------------- /ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon20x20@2x.png -------------------------------------------------------------------------------- /ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon20x20@3x.png -------------------------------------------------------------------------------- /ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon29x29@2x.png -------------------------------------------------------------------------------- /ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon29x29@3x.png -------------------------------------------------------------------------------- /ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon40x40@2x.png -------------------------------------------------------------------------------- /ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon40x40@3x.png -------------------------------------------------------------------------------- /ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon60x60@2x.png -------------------------------------------------------------------------------- /ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/ios/GCore/Images.xcassets/AppIcon.appiconset/AppIcon60x60@3x.png -------------------------------------------------------------------------------- /ios/GCore/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "AppIcon20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "AppIcon20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "AppIcon29x29@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "AppIcon29x29@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "AppIcon40x40@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "AppIcon40x40@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "AppIcon60x60@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "AppIcon60x60@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "1024x1024", 53 | "idiom" : "ios-marketing", 54 | "filename" : "AppIcon1024x024.png", 55 | "scale" : "1x" 56 | } 57 | ], 58 | "info" : { 59 | "version" : 1, 60 | "author" : "xcode" 61 | } 62 | } -------------------------------------------------------------------------------- /ios/GCore/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ios/GCore/Images.xcassets/LaunchImage.launchimage/1242x2208.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/ios/GCore/Images.xcassets/LaunchImage.launchimage/1242x2208.png -------------------------------------------------------------------------------- /ios/GCore/Images.xcassets/LaunchImage.launchimage/640x1136.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/ios/GCore/Images.xcassets/LaunchImage.launchimage/640x1136.png -------------------------------------------------------------------------------- /ios/GCore/Images.xcassets/LaunchImage.launchimage/640x960.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/ios/GCore/Images.xcassets/LaunchImage.launchimage/640x960.png -------------------------------------------------------------------------------- /ios/GCore/Images.xcassets/LaunchImage.launchimage/750x1334.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/ios/GCore/Images.xcassets/LaunchImage.launchimage/750x1334.png -------------------------------------------------------------------------------- /ios/GCore/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "11.0", 8 | "subtype" : "2436h", 9 | "scale" : "3x" 10 | }, 11 | { 12 | "extent" : "full-screen", 13 | "idiom" : "iphone", 14 | "subtype" : "736h", 15 | "filename" : "1242x2208.png", 16 | "minimum-system-version" : "8.0", 17 | "orientation" : "portrait", 18 | "scale" : "3x" 19 | }, 20 | { 21 | "extent" : "full-screen", 22 | "idiom" : "iphone", 23 | "subtype" : "667h", 24 | "filename" : "750x1334.png", 25 | "minimum-system-version" : "8.0", 26 | "orientation" : "portrait", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "orientation" : "portrait", 31 | "idiom" : "iphone", 32 | "filename" : "640x960.png", 33 | "extent" : "full-screen", 34 | "minimum-system-version" : "7.0", 35 | "scale" : "2x" 36 | }, 37 | { 38 | "extent" : "full-screen", 39 | "idiom" : "iphone", 40 | "subtype" : "retina4", 41 | "filename" : "640x1136.png", 42 | "minimum-system-version" : "7.0", 43 | "orientation" : "portrait", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } -------------------------------------------------------------------------------- /ios/GCore/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | GCore 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | 32 | NSLocationWhenInUseUsageDescription 33 | 34 | UIBackgroundModes 35 | 36 | audio 37 | 38 | UILaunchStoryboardName 39 | LaunchScreen 40 | UIRequiredDeviceCapabilities 41 | 42 | armv7 43 | 44 | UISupportedInterfaceOrientations 45 | 46 | UIInterfaceOrientationPortrait 47 | 48 | UIViewControllerBasedStatusBarAppearance 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /ios/GCore/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 | -------------------------------------------------------------------------------- /ios/GCoreTests/GCoreTests.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 14 | #import 15 | 16 | #define TIMEOUT_SECONDS 600 17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" 18 | 19 | @interface GCoreTests : XCTestCase 20 | 21 | @end 22 | 23 | @implementation GCoreTests 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 = [[[RCTSharedApplication() 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 | -------------------------------------------------------------------------------- /ios/GCoreTests/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 | -------------------------------------------------------------------------------- /ios/bridge.swift: -------------------------------------------------------------------------------- 1 | // 2 | // bridge.swift 3 | // GCore 4 | // 5 | // Created by leon on 2018/1/25. 6 | // Copyright © 2018年 Facebook. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | -------------------------------------------------------------------------------- /ios/dump.swift: -------------------------------------------------------------------------------- 1 | // 2 | // dump.swift 3 | // GCore 4 | // 5 | // Created by leon on 2018/1/26. 6 | // Copyright © 2018年 Facebook. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | -------------------------------------------------------------------------------- /ios/empty.swift: -------------------------------------------------------------------------------- 1 | // 2 | // empty.swift 3 | // GCore 4 | // 5 | // Created by leon on 2018/1/26. 6 | // Copyright © 2018年 Facebook. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GCore", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "node node_modules/react-native/local-cli/cli.js start", 7 | "test": "jest" 8 | }, 9 | "dependencies": { 10 | "prop-types": "^15.6.0", 11 | "react": "^16.0.0-alpha.12", 12 | "react-native": "0.52.0", 13 | "react-native-deprecated-custom-components": "^0.1.1", 14 | "react-native-fs": "^2.3.2", 15 | "react-native-looped-carousel": "^0.1.5", 16 | "react-native-progress": "^3.2.1", 17 | "react-native-scrollable-tab-view": "^0.7.3", 18 | "react-native-sqlite-storage": "^3.3.1", 19 | "react-native-storage": "^0.1.5", 20 | "react-native-swipe-list-view": "^0.4.1", 21 | "react-native-track-player": "^0.2.2", 22 | "react-native-wechat": "^1.9.2", 23 | "react-redux": "^5.0.3", 24 | "react-timer-mixin": "^0.13.3", 25 | "redux": "^3.6.0", 26 | "redux-promise": "^0.5.3", 27 | "redux-thunk": "^2.2.0" 28 | }, 29 | "devDependencies": { 30 | "babel-jest": "19.0.0", 31 | "babel-preset-react-native": "1.9.1", 32 | "jest": "19.0.2", 33 | "react-test-renderer": "15.4.2" 34 | }, 35 | "jest": { 36 | "preset": "react-native" 37 | }, 38 | "optionalDependencies": {} 39 | } 40 | -------------------------------------------------------------------------------- /player-handler.js: -------------------------------------------------------------------------------- 1 | import TrackPlayer from 'react-native-track-player' 2 | 3 | module.exports = async (data) =>{ 4 | if(data.type == 'playback-state') { 5 | }else if(data.type == 'remote-play') { 6 | TrackPlayer.play(); 7 | } else if(data.type == 'remote-seek') { 8 | TrackPlayer.seekTo(data.position); 9 | }else if (data.type == 'remote-stop') { 10 | TrackPlayer.stop(); 11 | }else if (data.type == 'remote-pause') { 12 | TrackPlayer.pause(); 13 | } 14 | 15 | }; -------------------------------------------------------------------------------- /screenShot/pic1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/screenShot/pic1.png -------------------------------------------------------------------------------- /screenShot/pic2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d2rivendell/react-native-GCore/dc86c43e6a54f4d2f3614c1a5ac7a93d4c8477b2/screenShot/pic2.png --------------------------------------------------------------------------------