├── .watchmanconfig ├── .gitattributes ├── .babelrc ├── app.json ├── src ├── utils │ ├── webIM │ │ ├── Sdk │ │ │ ├── index.js │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── src │ │ │ │ ├── emoji.js │ │ │ │ ├── status.js │ │ │ │ └── queue.js │ │ │ └── gulpfile.js │ │ ├── Api.js │ │ ├── WebIMConfig.js │ │ └── index.js │ ├── tool.js │ └── request.js ├── assets │ ├── psd │ │ ├── home.psd │ │ ├── job.psd │ │ ├── zone.psd │ │ └── notic.psd │ └── images │ │ ├── add.png │ │ ├── back.png │ │ ├── edit.png │ │ ├── like.png │ │ ├── logo.png │ │ ├── post.png │ │ ├── send.png │ │ ├── user.png │ │ ├── clean.png │ │ ├── close.png │ │ ├── github.png │ │ ├── group.png │ │ ├── header.png │ │ ├── home_0.png │ │ ├── home_1.png │ │ ├── job_0.png │ │ ├── job_1.png │ │ ├── liked.png │ │ ├── notice.png │ │ ├── public.png │ │ ├── reply.png │ │ ├── search.png │ │ ├── zone_0.png │ │ ├── zone_1.png │ │ ├── collect.png │ │ ├── collected.png │ │ ├── comment.png │ │ ├── history.png │ │ ├── integral.png │ │ ├── launch_bg.png │ │ ├── notic_0.png │ │ ├── notic_1.png │ │ ├── recruit.png │ │ ├── searchbar.png │ │ ├── setting.png │ │ └── collection.png ├── screenshot │ ├── chat.gif │ ├── home.gif │ ├── search.gif │ ├── 531504842468_.pic.jpg │ ├── 541504842490_.pic.jpg │ ├── 551504842567_.pic.jpg │ ├── 571504842628_.pic.jpg │ ├── 581504842670_.pic.jpg │ ├── 591504844116_.pic.jpg │ ├── 611504844236_.pic.jpg │ ├── 621504844256_.pic.jpg │ ├── 631504846801_.pic.jpg │ ├── 511504842345_.pic_hd.jpg │ ├── 521504842419_.pic_hd.jpg │ ├── 561504842591_.pic_hd.jpg │ ├── 601504844171_.pic_hd.jpg │ ├── WX20170925-171924@2x.png │ ├── WX20170925-171942@2x.png │ ├── WX20170925-171950@2x.png │ └── WX20170925-173126@2x.png ├── components │ ├── index.js │ ├── Tip.js │ ├── HtmlView.js │ └── Html.js ├── config.js ├── index.js ├── pages │ ├── publish │ │ ├── service.js │ │ ├── model.js │ │ ├── components │ │ │ ├── Content.js │ │ │ ├── Option.js │ │ │ └── Title.js │ │ └── index.js │ ├── notice │ │ ├── components │ │ │ ├── Notice.js │ │ │ ├── Seek.js │ │ │ ├── Message.js │ │ │ └── ChatRow.js │ │ └── screen │ │ │ ├── Read.js │ │ │ ├── Contact.js │ │ │ ├── AddFriend.js │ │ │ ├── System.js │ │ │ ├── Chat.js │ │ │ └── Roster.js │ ├── search │ │ ├── components │ │ │ ├── Card.js │ │ │ ├── Seek.js │ │ │ └── History.js │ │ ├── service.js │ │ ├── model.js │ │ └── index.js │ ├── home │ │ ├── service.js │ │ ├── model.js │ │ └── components │ │ │ └── Wrap.js │ ├── recruit │ │ ├── service.js │ │ ├── model.js │ │ ├── components │ │ │ └── Wrap.js │ │ └── index.js │ ├── zone │ │ ├── screen │ │ │ ├── Github.js │ │ │ ├── Password.js │ │ │ ├── Dynamic.js │ │ │ ├── Collect.js │ │ │ ├── Login.js │ │ │ ├── Center.js │ │ │ └── Credits.js │ │ ├── components │ │ │ ├── Card.js │ │ │ └── Header.js │ │ ├── service.js │ │ └── model.js │ └── detail │ │ ├── components │ │ ├── Option.js │ │ └── Info.js │ │ ├── model.js │ │ └── service.js ├── model.js └── navigation.js ├── android ├── settings.gradle ├── app │ ├── src │ │ └── main │ │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ └── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── java │ │ │ └── com │ │ │ │ └── cnodejs │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ │ └── AndroidManifest.xml │ ├── BUCK │ └── proguard-rules.pro ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── keystores │ ├── debug.keystore.properties │ └── BUCK ├── build.gradle ├── gradle.properties └── gradlew.bat ├── .buckconfig ├── jsconfig.json ├── index.android.js ├── index.ios.js ├── __tests__ ├── index.ios.js └── index.android.js ├── ios ├── cnodejs │ ├── AppDelegate.h │ ├── main.m │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── AppDelegate.m │ ├── Info.plist │ └── Base.lproj │ │ └── LaunchScreen.xib ├── cnodejsTests │ ├── Info.plist │ └── cnodejsTests.m ├── cnodejs-tvOSTests │ └── Info.plist └── cnodejs-tvOS │ └── Info.plist ├── .eslintrc.js ├── package.json ├── .gitignore ├── .vscode ├── launch.json └── .react │ └── debuggerWorker.js ├── .flowconfig └── README.md /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react-native"] 3 | } 4 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cnodejs", 3 | "displayName": "cnodejs" 4 | } -------------------------------------------------------------------------------- /src/utils/webIM/Sdk/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./src/connection') 2 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'cnodejs' 2 | 3 | include ':app' 4 | -------------------------------------------------------------------------------- /src/assets/psd/home.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/psd/home.psd -------------------------------------------------------------------------------- /src/assets/psd/job.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/psd/job.psd -------------------------------------------------------------------------------- /src/assets/psd/zone.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/psd/zone.psd -------------------------------------------------------------------------------- /src/screenshot/chat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/chat.gif -------------------------------------------------------------------------------- /src/screenshot/home.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/home.gif -------------------------------------------------------------------------------- /src/assets/images/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/add.png -------------------------------------------------------------------------------- /src/assets/images/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/back.png -------------------------------------------------------------------------------- /src/assets/images/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/edit.png -------------------------------------------------------------------------------- /src/assets/images/like.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/like.png -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/logo.png -------------------------------------------------------------------------------- /src/assets/images/post.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/post.png -------------------------------------------------------------------------------- /src/assets/images/send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/send.png -------------------------------------------------------------------------------- /src/assets/images/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/user.png -------------------------------------------------------------------------------- /src/assets/psd/notic.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/psd/notic.psd -------------------------------------------------------------------------------- /src/screenshot/search.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/search.gif -------------------------------------------------------------------------------- /src/assets/images/clean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/clean.png -------------------------------------------------------------------------------- /src/assets/images/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/close.png -------------------------------------------------------------------------------- /src/assets/images/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/github.png -------------------------------------------------------------------------------- /src/assets/images/group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/group.png -------------------------------------------------------------------------------- /src/assets/images/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/header.png -------------------------------------------------------------------------------- /src/assets/images/home_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/home_0.png -------------------------------------------------------------------------------- /src/assets/images/home_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/home_1.png -------------------------------------------------------------------------------- /src/assets/images/job_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/job_0.png -------------------------------------------------------------------------------- /src/assets/images/job_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/job_1.png -------------------------------------------------------------------------------- /src/assets/images/liked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/liked.png -------------------------------------------------------------------------------- /src/assets/images/notice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/notice.png -------------------------------------------------------------------------------- /src/assets/images/public.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/public.png -------------------------------------------------------------------------------- /src/assets/images/reply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/reply.png -------------------------------------------------------------------------------- /src/assets/images/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/search.png -------------------------------------------------------------------------------- /src/assets/images/zone_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/zone_0.png -------------------------------------------------------------------------------- /src/assets/images/zone_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/zone_1.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | cnodejs 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/collect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/collect.png -------------------------------------------------------------------------------- /src/assets/images/collected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/collected.png -------------------------------------------------------------------------------- /src/assets/images/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/comment.png -------------------------------------------------------------------------------- /src/assets/images/history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/history.png -------------------------------------------------------------------------------- /src/assets/images/integral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/integral.png -------------------------------------------------------------------------------- /src/assets/images/launch_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/launch_bg.png -------------------------------------------------------------------------------- /src/assets/images/notic_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/notic_0.png -------------------------------------------------------------------------------- /src/assets/images/notic_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/notic_1.png -------------------------------------------------------------------------------- /src/assets/images/recruit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/recruit.png -------------------------------------------------------------------------------- /src/assets/images/searchbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/searchbar.png -------------------------------------------------------------------------------- /src/assets/images/setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/setting.png -------------------------------------------------------------------------------- /src/assets/images/collection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/assets/images/collection.png -------------------------------------------------------------------------------- /src/screenshot/531504842468_.pic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/531504842468_.pic.jpg -------------------------------------------------------------------------------- /src/screenshot/541504842490_.pic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/541504842490_.pic.jpg -------------------------------------------------------------------------------- /src/screenshot/551504842567_.pic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/551504842567_.pic.jpg -------------------------------------------------------------------------------- /src/screenshot/571504842628_.pic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/571504842628_.pic.jpg -------------------------------------------------------------------------------- /src/screenshot/581504842670_.pic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/581504842670_.pic.jpg -------------------------------------------------------------------------------- /src/screenshot/591504844116_.pic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/591504844116_.pic.jpg -------------------------------------------------------------------------------- /src/screenshot/611504844236_.pic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/611504844236_.pic.jpg -------------------------------------------------------------------------------- /src/screenshot/621504844256_.pic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/621504844256_.pic.jpg -------------------------------------------------------------------------------- /src/screenshot/631504846801_.pic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/631504846801_.pic.jpg -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/screenshot/511504842345_.pic_hd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/511504842345_.pic_hd.jpg -------------------------------------------------------------------------------- /src/screenshot/521504842419_.pic_hd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/521504842419_.pic_hd.jpg -------------------------------------------------------------------------------- /src/screenshot/561504842591_.pic_hd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/561504842591_.pic_hd.jpg -------------------------------------------------------------------------------- /src/screenshot/601504844171_.pic_hd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/601504844171_.pic_hd.jpg -------------------------------------------------------------------------------- /src/screenshot/WX20170925-171924@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/WX20170925-171924@2x.png -------------------------------------------------------------------------------- /src/screenshot/WX20170925-171942@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/WX20170925-171942@2x.png -------------------------------------------------------------------------------- /src/screenshot/WX20170925-171950@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/WX20170925-171950@2x.png -------------------------------------------------------------------------------- /src/screenshot/WX20170925-173126@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/src/screenshot/WX20170925-173126@2x.png -------------------------------------------------------------------------------- /.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | import Tip from './Tip'; 2 | import Html from './Html'; 3 | import HtmlView from './HtmlView'; 4 | 5 | export { Tip, Html, HtmlView } -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | const HOME_URL = process.env.NODE_ENV === 'production' ? 'https://cnodejs.org/api/v1' : 'https://cnodejs.org/api/v1' 2 | 3 | export { HOME_URL } -------------------------------------------------------------------------------- /android/keystores/debug.keystore.properties: -------------------------------------------------------------------------------- 1 | key.store=debug.keystore 2 | key.alias=androiddebugkey 3 | key.store.password=android 4 | key.alias.password=android 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whlin1115/react-native-cnodejs/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "allowSyntheticDefaultImports": true 5 | }, 6 | "exclude": [ 7 | "node_modules" 8 | ] 9 | } -------------------------------------------------------------------------------- /android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = "debug", 3 | properties = "debug.keystore.properties", 4 | store = "debug.keystore", 5 | visibility = [ 6 | "PUBLIC", 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /src/utils/webIM/Sdk/README.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 1.1.4 4 | 5 | * add browser version support umd 6 | * remove strophe from sdk because it't too big for webpack or other compiler 7 | 8 | ## todo 9 | 10 | * version semver -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 6 | -------------------------------------------------------------------------------- /index.android.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { AppRegistry } from 'react-native'; 9 | import App from './src/index'; 10 | 11 | AppRegistry.registerComponent('cnodejs', () => App); 12 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import dva from 'dva/mobile'; 3 | import models from './model'; 4 | import Navigation from './navigation'; 5 | 6 | const app = dva(); 7 | 8 | Object.keys(models).map(key => app.model(models[key])); 9 | 10 | app.router(() => ); 11 | export default app.start() 12 | -------------------------------------------------------------------------------- /index.ios.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { AppRegistry } from 'react-native'; 9 | import App from './src/index'; 10 | 11 | AppRegistry.registerComponent('cnodejs', () => App); 12 | 13 | -------------------------------------------------------------------------------- /src/pages/publish/service.js: -------------------------------------------------------------------------------- 1 | import { get, post } from '../../utils/request'; 2 | import { moment } from '../../utils/tool'; 3 | 4 | export async function createTopic(params) { 5 | return post('/topics', params); 6 | } 7 | 8 | export async function updateTopic(params) { 9 | return post('/topics/update', params); 10 | } 11 | -------------------------------------------------------------------------------- /__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 | -------------------------------------------------------------------------------- /__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 | -------------------------------------------------------------------------------- /src/model.js: -------------------------------------------------------------------------------- 1 | import home from './pages/home/model'; 2 | import detail from './pages/detail/model'; 3 | import search from './pages/search/model'; 4 | import zone from './pages/zone/model'; 5 | import publish from './pages/publish/model'; 6 | import notice from './pages/notice/model'; 7 | import recruit from './pages/recruit/model'; 8 | 9 | export default { home, detail, search, zone, publish, notice, recruit } -------------------------------------------------------------------------------- /android/app/src/main/java/com/cnodejs/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.cnodejs; 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 "cnodejs"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ios/cnodejs/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 | -------------------------------------------------------------------------------- /src/components/Tip.js: -------------------------------------------------------------------------------- 1 | 2 | import React from 'react' 3 | import { StyleSheet, View, Image, Text } from 'react-native' 4 | 5 | function Tip({ message }) { 6 | 7 | return ( 8 | 9 | {message.text} 10 | 11 | ) 12 | } 13 | 14 | const styles = StyleSheet.create({ 15 | messageView: { 16 | padding: 30, 17 | justifyContent: 'center', 18 | }, 19 | 20 | message: { 21 | textAlign: 'center', 22 | fontSize: 14, 23 | color: '#999' 24 | }, 25 | }); 26 | 27 | export default Tip 28 | -------------------------------------------------------------------------------- /ios/cnodejs/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 | -------------------------------------------------------------------------------- /src/components/HtmlView.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | import HTMLView from 'react-native-htmlview'; 4 | 5 | class HtmlView extends React.Component { 6 | render() { 7 | const { html, styles } = this.props; 8 | 9 | const _renderNode = function (node, index, siblings, parent, defaultRenderer) { 10 | if (node.name == 'img') { 11 | const name = node.name 12 | return null 13 | } 14 | } 15 | 16 | return ( 17 | 22 | ); 23 | } 24 | } 25 | 26 | export default HtmlView -------------------------------------------------------------------------------- /src/components/Html.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { StyleSheet, Image, Dimensions } from 'react-native' 3 | import HtmlRender from 'react-native-html-render' 4 | 5 | class Html extends Component { 6 | constructor(props) { 7 | super(props) 8 | } 9 | 10 | render() { 11 | const { html } = this.props; 12 | const sample = "
Hello World
"; 13 | 14 | return ( 15 | html ? 16 | : null 20 | ) 21 | } 22 | } 23 | 24 | const styles = StyleSheet.create({ 25 | img: { 26 | width: 100, 27 | height: 100 28 | } 29 | }) 30 | 31 | export default Html -------------------------------------------------------------------------------- /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:2.2.3' 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 | -------------------------------------------------------------------------------- /ios/cnodejs/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "browser": true, 4 | "commonjs": true, 5 | "es6": true 6 | }, 7 | "extends": "eslint:recommended", 8 | "parserOptions": { 9 | "ecmaFeatures": { 10 | "experimentalObjectRestSpread": true, 11 | "jsx": true 12 | }, 13 | "sourceType": "module" 14 | }, 15 | "plugins": [ 16 | "react" 17 | ], 18 | "rules": { 19 | "indent": [ 20 | "error", 21 | 4 22 | ], 23 | "linebreak-style": [ 24 | "error", 25 | "unix" 26 | ], 27 | "quotes": [ 28 | "error", 29 | "single" 30 | ], 31 | "semi": [ 32 | "error", 33 | "always" 34 | ] 35 | } 36 | }; -------------------------------------------------------------------------------- /ios/cnodejsTests/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/cnodejs-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 | -------------------------------------------------------------------------------- /src/pages/notice/components/Notice.js: -------------------------------------------------------------------------------- 1 | 2 | import React from 'react' 3 | import { StyleSheet, View, Image, Text, TouchableOpacity } from 'react-native' 4 | 5 | function Notice({ item }) { 6 | 7 | return ( 8 | 9 | {item.title} 10 | 11 | {item.content} 12 | 13 | 14 | ) 15 | } 16 | 17 | const styles = StyleSheet.create({ 18 | container: { 19 | margin: 10, 20 | marginBottom: 0, 21 | padding: 15, 22 | backgroundColor: '#FFFFFF', 23 | }, 24 | 25 | content: { 26 | marginTop: 10, 27 | }, 28 | 29 | text: { 30 | fontSize: 14, 31 | lineHeight: 20, 32 | color: '#999', 33 | }, 34 | 35 | h3: { 36 | fontSize: 16, 37 | }, 38 | }); 39 | 40 | export default Notice 41 | -------------------------------------------------------------------------------- /src/utils/webIM/Sdk/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "easemob-websdk", 3 | "version": "1.1.7", 4 | "description": "Easemob im websdk", 5 | "keywords": [ 6 | "realtime", 7 | "im", 8 | "easemob", 9 | "xmpp", 10 | "strophe" 11 | ], 12 | "main": "index.js", 13 | "scripts": { 14 | "build": "gulp", 15 | "test": "echo \"Error: no test specified\" && exit 1" 16 | }, 17 | "author": "WytheMe", 18 | "license": "MIT", 19 | "dependencies": {}, 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/easemob/web-im" 23 | }, 24 | "devDependencies": { 25 | "gulp-rename": "^1.2.2", 26 | "browserify": "^13.1.1", 27 | "gulp-sourcemaps": "^2.2.0", 28 | "gulp-uglify": "^2.0.0", 29 | "gulp-util": "^3.0.7", 30 | "vinyl-buffer": "^1.0.0", 31 | "vinyl-source-stream": "^1.1.0", 32 | "webpack-stream": "^3.2.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cnodejs", 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 | "cheerio-without-node-native": "^0.20.2", 11 | "dva": "1.3.0-beta.3", 12 | "lodash": "^4.17.4", 13 | "moment": "^2.18.1", 14 | "react": "16.0.0-alpha.12", 15 | "react-native": "0.47.2", 16 | "react-native-gifted-chat": "^0.2.7", 17 | "react-native-html-render": "^1.0.5", 18 | "react-native-htmlview": "^0.12.0", 19 | "react-native-scrollable-tab-view": "0.6.6", 20 | "react-navigation": "^1.0.0-beta.11", 21 | "xmldom": "^0.1.27" 22 | }, 23 | "devDependencies": { 24 | "babel-jest": "20.0.3", 25 | "babel-preset-react-native": "2.1.0", 26 | "eslint": "^4.5.0", 27 | "eslint-plugin-react": "^7.3.0", 28 | "jest": "20.0.4", 29 | "react-test-renderer": "16.0.0-alpha.12" 30 | }, 31 | "jest": { 32 | "preset": "react-native" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.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://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 50 | 51 | fastlane/report.xml 52 | fastlane/Preview.html 53 | fastlane/screenshots 54 | -------------------------------------------------------------------------------- /src/pages/search/components/Card.js: -------------------------------------------------------------------------------- 1 | 2 | import React from 'react' 3 | import { StyleSheet, View, Image, Text, TouchableOpacity } from 'react-native' 4 | 5 | function Card({ item, navigate }) { 6 | 7 | return ( 8 | { navigate('Detail', { topic_id: item.id }) }}> 9 | 10 | {item.title} 11 | 12 | {item.content} 13 | 14 | 15 | 16 | ) 17 | } 18 | 19 | const styles = StyleSheet.create({ 20 | list: { 21 | margin: 10, 22 | marginBottom: 0, 23 | padding: 15, 24 | backgroundColor: '#FFF', 25 | }, 26 | 27 | h3: { 28 | fontSize: 16, 29 | }, 30 | 31 | content: { 32 | marginTop: 10, 33 | }, 34 | 35 | b: { 36 | fontSize: 14, 37 | lineHeight: 24, 38 | color: '#999', 39 | }, 40 | }); 41 | 42 | export default Card 43 | -------------------------------------------------------------------------------- /src/utils/webIM/Sdk/src/emoji.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | map: { 3 | '[):]': 'grinning', 4 | '[:D]': 'smiley', 5 | '[;)]': 'wink', 6 | '[:-o]': 'sweat_smile', 7 | '[:p]': 'yum', 8 | '[(H)]': 'sunglasses', 9 | '[:@]': 'rage', 10 | '[:s]': 'confounded', 11 | '[:$]': 'flushed', 12 | '[:(]': 'disappointed', 13 | '[:\'(]': 'sob', 14 | '[:|]': 'neutral_face', 15 | '[(a)]': 'innocent', 16 | '[8o|]': 'grin', 17 | '[8-|]': 'smirk', 18 | '[+o(]': 'scream', 19 | '[ { 12 | const create_at = moment(topic.create_at).startOf('minute').fromNow() 13 | const last_reply_at = moment(topic.last_reply_at).startOf('minute').fromNow() 14 | const avatar_url = topic.author.avatar_url 15 | if (avatar_url && !avatar_url.startsWith('https')) topic.author.avatar_url = 'https:' + avatar_url 16 | let tab = topic.tab ? topic.tab : 'default' 17 | if (topic.top) tab = 'top' 18 | if (topic.good) tab = 'good' 19 | const sort = tabs[tab] 20 | const title = topic.title.replace(/[\r\n]/g, '') 21 | return { ...topic, create_at, last_reply_at, tab, title, sort } 22 | }) 23 | return topics 24 | } -------------------------------------------------------------------------------- /android/app/src/main/java/com/cnodejs/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.cnodejs; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.react.ReactApplication; 6 | import com.facebook.react.ReactNativeHost; 7 | import com.facebook.react.ReactPackage; 8 | import com.facebook.react.shell.MainReactPackage; 9 | import com.facebook.soloader.SoLoader; 10 | 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | public class MainApplication extends Application implements ReactApplication { 15 | 16 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 17 | @Override 18 | public boolean getUseDeveloperSupport() { 19 | return BuildConfig.DEBUG; 20 | } 21 | 22 | @Override 23 | protected List getPackages() { 24 | return Arrays.asList( 25 | new MainReactPackage() 26 | ); 27 | } 28 | }; 29 | 30 | @Override 31 | public ReactNativeHost getReactNativeHost() { 32 | return mReactNativeHost; 33 | } 34 | 35 | @Override 36 | public void onCreate() { 37 | super.onCreate(); 38 | SoLoader.init(this, /* native exopackage */ false); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/pages/search/service.js: -------------------------------------------------------------------------------- 1 | import { requestHtml } from '../../utils/request'; 2 | import { moment } from '../../utils/tool'; 3 | import cheerio from 'cheerio-without-node-native'; 4 | 5 | export async function querySearch(params) { 6 | const { content, page = 1 } = params 7 | return requestHtml(`https://m.baidu.com/from=844b/s?pn=${page}0&usm=1&word=site%3Acnodejs.org+${content}`) 8 | } 9 | 10 | export function parseSearch(data) { 11 | const $ = cheerio.load(data); 12 | var lists = []; 13 | const results = $('#results .c-result') 14 | results.each(function (i, elem) { 15 | const dataLog = $(this).attr('data-log').replace(/'/g, '"') 16 | const id = JSON.parse(dataLog).mu.replace(/.*?topic\/(.*?)$/, '$1') 17 | const title = $(this).find('h3').text() 18 | const content = $(this).find('p').text() 19 | const list = { id, title, content }; 20 | if (id.length == 24) lists.push(list) // 话题ID长度 21 | }); 22 | return lists; 23 | } 24 | 25 | export function parseRecords(state, content) { 26 | const records = state.records.filter(history => history !== content); 27 | if (records.length > 9) records.shift(); 28 | records.unshift(content); 29 | return { records }; 30 | } -------------------------------------------------------------------------------- /src/pages/recruit/service.js: -------------------------------------------------------------------------------- 1 | import { get } from '../../utils/request'; 2 | import { moment, city } from '../../utils/tool'; 3 | 4 | export async function queryTopics(params) { 5 | const { page = 1, tab = 'job', limit = 20, mdrender = true } = params 6 | return get(`/topics?page=${page}&limit=${limit}&tab=${tab}&mdrender=${mdrender}`); 7 | } 8 | 9 | export function parseTopics(data) { 10 | const topics = data.map(topic => { 11 | const create_at = moment(topic.create_at).startOf('minute').fromNow() 12 | const last_reply_at = moment(topic.last_reply_at).startOf('minute').fromNow() 13 | const avatar_url = topic.author.avatar_url 14 | if (!avatar_url.startsWith('https')) topic.author.avatar_url = 'https:' + avatar_url 15 | const title = topic.title.replace(/[\r\n]/g, '') 16 | const location = title.match(/[\u4E00-\u9FA5]{2}/) 17 | let sort = '暂无' 18 | if (location) sort = location[0] 19 | var tab = 'default' 20 | for (var l in city) { 21 | var line = String(city[l]) 22 | if (line.indexOf(sort) > -1) { 23 | var tab = l 24 | break 25 | } 26 | } 27 | return { ...topic, create_at, last_reply_at, tab, title, sort } 28 | }) 29 | return topics 30 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/utils/tool.js: -------------------------------------------------------------------------------- 1 | import moment from 'moment'; 2 | import 'moment/locale/zh-cn'; 3 | moment.locale('zh-cn'); 4 | 5 | const formatDate = function (str) { 6 | const date = new Date(str); 7 | const time = new Date().getTime() - date.getTime(); 8 | if (time < 0) { 9 | return ''; 10 | } else if (time / 1000 < 60) { 11 | return '刚刚'; 12 | } else if ((time / 60000) < 60) { 13 | return parseInt((time / 60000)) + '分钟前'; 14 | } else if ((time / 3600000) < 24) { 15 | return parseInt(time / 3600000) + '小时前'; 16 | } else if ((time / 86400000) < 31) { 17 | return parseInt(time / 86400000) + '天前'; 18 | } else if ((time / 2592000000) < 12) { 19 | return parseInt(time / 2592000000) + '个月前'; 20 | } else { 21 | let year = parseInt(time / 31536000000) 22 | year = year ? year : 1 23 | return year + '年前'; 24 | } 25 | }; 26 | 27 | const city = { 28 | 'one': ['北京市', '上海市', '广州市', '深圳市'], 29 | 'new': ['成都市', '杭州市', '武汉市', '重庆市', '南京市', '天津市', '苏州市', '西安市', '长沙市', '沈阳市', '青岛市', '郑州市', '大连市', '东莞市', '宁波市'], 30 | 'two': ['厦门市', '福州市', '无锡市', '合肥市', '昆明市', '哈尔滨市', '济南市', '佛山市', '长春市', '温州市', '石家庄市', '南宁市', '常州市', '泉州市', '南昌市', '贵阳市', '太原市', '烟台市', '嘉兴市', '南通市', '金华市', '珠海市', '惠州市', '徐州市', '海口市', '乌鲁木齐市', '绍兴市', '中山市', '台州市', '兰州市'], 31 | } 32 | 33 | export { formatDate, moment, city } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | 5 | { 6 | "name": "Debug Android", 7 | "program": "${workspaceRoot}/.vscode/launchReactNative.js", 8 | "type": "reactnative", 9 | "request": "launch", 10 | "platform": "android", 11 | "sourceMaps": true, 12 | "outDir": "${workspaceRoot}/.vscode/.react" 13 | }, 14 | { 15 | "name": "Debug iOS", 16 | "program": "${workspaceRoot}/.vscode/launchReactNative.js", 17 | "type": "reactnative", 18 | "request": "launch", 19 | "platform": "ios", 20 | "target": "iPhone 6", 21 | "sourceMaps": true, 22 | "outDir": "${workspaceRoot}/.vscode/.react" 23 | }, 24 | { 25 | "name": "Attach to packager", 26 | "program": "${workspaceRoot}/.vscode/launchReactNative.js", 27 | "type": "reactnative", 28 | "request": "attach", 29 | "sourceMaps": true, 30 | "outDir": "${workspaceRoot}/.vscode/.react" 31 | }, 32 | { 33 | "name": "Debug in Exponent", 34 | "program": "${workspaceRoot}/.vscode/launchReactNative.js", 35 | "type": "reactnative", 36 | "request": "launch", 37 | "platform": "exponent", 38 | "sourceMaps": true, 39 | "outDir": "${workspaceRoot}/.vscode/.react" 40 | } 41 | ] 42 | } -------------------------------------------------------------------------------- /src/pages/recruit/model.js: -------------------------------------------------------------------------------- 1 | import * as service from './service'; 2 | 3 | export default { 4 | namespace: 'recruit', 5 | state: { 6 | page: 1, 7 | data: [], 8 | loading: false, 9 | }, 10 | effects: { 11 | *query({ payload = {} }, { call, put }) { 12 | const { page = 1 } = payload 13 | yield put({ type: 'loading', payload: true }); 14 | const { data, err } = yield call(service.queryTopics, payload); 15 | yield put({ type: 'loading', payload: false }); 16 | if (err) return console.log(err) 17 | yield put({ type: 'page', payload: page }); 18 | if (page == 1) yield put({ type: 'query/success', payload: data }); 19 | else yield put({ type: 'more/success', payload: data }); 20 | }, 21 | }, 22 | reducers: { 23 | 'query/success'(state, { payload }) { 24 | const [, data] = payload 25 | const topics = service.parseTopics(data.data) 26 | return { ...state, data: topics }; 27 | }, 28 | 'more/success'(state, { payload }) { 29 | const [, data] = payload 30 | const topics = service.parseTopics(data.data) 31 | return { ...state, data: [...state.data, ...topics] }; 32 | }, 33 | 'page'(state, { payload: data }) { 34 | return { ...state, page: data }; 35 | }, 36 | 'loading'(state, { payload: data }) { 37 | return { ...state, loading: data }; 38 | }, 39 | }, 40 | subscriptions: {}, 41 | }; 42 | -------------------------------------------------------------------------------- /src/utils/webIM/Api.js: -------------------------------------------------------------------------------- 1 | // our "constructor" 2 | const create = (baseURL = '') => { 3 | 4 | function parseJSON(response) { 5 | return Promise.all([response, response.json()]) 6 | } 7 | 8 | function checkStatus(response) { 9 | if (response.status >= 200 && response.status < 300) { 10 | return response; 11 | } 12 | 13 | const error = new Error(response.statusText); 14 | error.response = response; 15 | throw error; 16 | } 17 | 18 | /** 19 | * Requests a URL, returning a promise. 20 | * 21 | * @param {string} url The URL we want to request 22 | * @param {object} [options] The options we want to pass to "fetch" 23 | * @return {object} An object containing either "data" or "err" 24 | */ 25 | function post(url, body) { 26 | url = baseURL + url; 27 | const options = { 28 | method: 'POST', 29 | headers: { 30 | 'Accept': 'application/json', 31 | 'Content-Type': 'application/json' 32 | }, 33 | body: JSON.stringify(body) 34 | } 35 | return fetch(url, options) 36 | .then(checkStatus) 37 | .then(parseJSON) 38 | .then(data => ({ data })) 39 | .catch(err => ({ err })); 40 | } 41 | 42 | return { 43 | register: (body) => post('/users', body), 44 | login: (body) => post('/token', body), 45 | } 46 | } 47 | 48 | // let's return back our create method as the default. 49 | export default { 50 | create 51 | } 52 | -------------------------------------------------------------------------------- /ios/cnodejs/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.ios" fallbackResource:nil]; 22 | 23 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 24 | moduleName:@"cnodejs" 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 | -------------------------------------------------------------------------------- /.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 | .*/Libraries/react-native/ReactNative.js 16 | 17 | [include] 18 | 19 | [libs] 20 | node_modules/react-native/Libraries/react-native/react-native-interface.js 21 | node_modules/react-native/flow 22 | flow/ 23 | 24 | [options] 25 | emoji=true 26 | 27 | module.system=haste 28 | 29 | munge_underscores=true 30 | 31 | 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' 32 | 33 | suppress_type=$FlowIssue 34 | suppress_type=$FlowFixMe 35 | suppress_type=$FixMe 36 | 37 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(4[0-9]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 38 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(4[0-9]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 39 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 40 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 41 | 42 | unsafe.enable_getters_and_setters=true 43 | 44 | [version] 45 | ^0.49.1 46 | -------------------------------------------------------------------------------- /src/utils/webIM/Sdk/gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | var gulp = require('gulp') 4 | var webpack = require('webpack-stream') 5 | var mocha = require('gulp-mocha') // 用于单元测试 6 | var babel = require('gulp-babel') // 用于ES6转化ES5 7 | // var browserify = require('browserify'); 8 | // var source = require('vinyl-source-stream'); 9 | // var buffer = require('vinyl-buffer'); 10 | var uglify = require('gulp-uglify') 11 | var rename = require('gulp-rename') 12 | var sourcemaps = require('gulp-sourcemaps') 13 | var gutil = require('gulp-util') 14 | 15 | // websdk.js 16 | // websdk.min.js 17 | // websdk.min.js.map 18 | gulp.task('sdk', ['sdk:umd', 'sdk:umd:min']) 19 | 20 | // websdk.js 21 | gulp.task('sdk:umd', function () { 22 | return gulp.src('./index.js') 23 | .pipe(webpack({ 24 | output: { 25 | filename: 'websdk.browser.js', 26 | library: 'WebIM', 27 | libraryTarget: 'umd' 28 | } 29 | }) 30 | ) 31 | .pipe(gulp.dest('dist/')) 32 | }) 33 | 34 | // websdk.min.js 35 | // websdk.min.js.map 36 | gulp.task('sdk:umd:min', ['sdk:umd'], function () { 37 | return gulp.src('./dist/websdk.browser.js') 38 | .pipe(sourcemaps.init({loadMaps: true})) 39 | .pipe(uglify()) 40 | .pipe(rename('websdk.browser.min.js')) 41 | .on('error', gutil.log) 42 | .pipe(sourcemaps.write('./')) 43 | .pipe(gulp.dest('dist/')) 44 | }) 45 | 46 | gulp.task('default', ['sdk']) 47 | 48 | // 49 | // gulp.task('watch', function() { 50 | // livereload.listen(); //要在这里调用listen()方法 51 | // gulp.watch('less/*.less', ['less']); 52 | // }); 53 | -------------------------------------------------------------------------------- /src/pages/zone/screen/Github.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | import { connect } from 'dva/mobile'; 3 | import { StyleSheet, View, Text, Button, Image, StatusBar, FlatList, Dimensions, TouchableOpacity } from 'react-native' 4 | 5 | class Github extends PureComponent { 6 | constructor(props) { 7 | super(props) 8 | this.state = {} 9 | } 10 | 11 | static navigationOptions = ({ navigation }) => { 12 | const { state, setParams } = navigation; 13 | return { 14 | headerTitle: 'GitHub', 15 | }; 16 | }; 17 | 18 | componentDidMount() { 19 | const { params } = this.props.navigation.state; 20 | // this.props.query(params) 21 | } 22 | 23 | componentWillReceiveProps(next) { 24 | const { params } = this.props; 25 | if (next.params !== params) { 26 | 27 | } 28 | } 29 | 30 | render() { 31 | const { data, loading } = this.props 32 | const { navigate } = this.props.navigation; 33 | const { width } = Dimensions.get('window'); 34 | return ( 35 | 36 | 37 | GitHub页面 38 | 39 | ); 40 | } 41 | } 42 | 43 | function mapStateToProps(state) { 44 | const { data, loading } = state.zone; 45 | return { data, loading }; 46 | } 47 | 48 | function mapDispatchToProps(dispatch) { 49 | return { 50 | query(params) { 51 | dispatch({ 52 | type: 'zone/query', 53 | payload: params, 54 | }); 55 | }, 56 | } 57 | } 58 | 59 | const styles = StyleSheet.create({ 60 | container: { 61 | flex: 1, 62 | backgroundColor: '#F8F8F8', 63 | }, 64 | }); 65 | 66 | export default connect(mapStateToProps, mapDispatchToProps)(Github); 67 | -------------------------------------------------------------------------------- /src/pages/zone/screen/Password.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | import { connect } from 'dva/mobile'; 3 | import { Tip } from '../../../components'; 4 | import { StyleSheet, View, Text, Button, Image, StatusBar, FlatList, Dimensions, TouchableOpacity } from 'react-native' 5 | 6 | class Password extends PureComponent { 7 | constructor(props) { 8 | super(props) 9 | this.state = {} 10 | } 11 | 12 | static navigationOptions = ({ navigation }) => { 13 | const { state, setParams } = navigation; 14 | return { 15 | headerTitle: '修改密码', 16 | }; 17 | }; 18 | 19 | componentDidMount() { 20 | const { params } = this.props.navigation.state; 21 | // this.props.query(params) 22 | } 23 | 24 | componentWillReceiveProps(next) { 25 | const { params } = this.props; 26 | if (next.params !== params) { 27 | 28 | } 29 | } 30 | 31 | render() { 32 | const { data, loading } = this.props 33 | const { navigate } = this.props.navigation; 34 | 35 | return ( 36 | 37 | 38 | 39 | 40 | ); 41 | } 42 | } 43 | 44 | function mapStateToProps(state) { 45 | const { data, loading } = state.zone; 46 | return { data, loading }; 47 | } 48 | 49 | function mapDispatchToProps(dispatch) { 50 | return { 51 | query(params) { 52 | dispatch({ 53 | type: 'zone/query', 54 | payload: params, 55 | }); 56 | }, 57 | } 58 | } 59 | 60 | const styles = StyleSheet.create({ 61 | container: { 62 | flex: 1, 63 | backgroundColor: '#F8F8F8', 64 | } 65 | }); 66 | 67 | export default connect(mapStateToProps, mapDispatchToProps)(Password); 68 | -------------------------------------------------------------------------------- /ios/cnodejs-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 | -------------------------------------------------------------------------------- /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.cnodejs", 49 | ) 50 | 51 | android_resource( 52 | name = "res", 53 | package = "com.cnodejs", 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 | -------------------------------------------------------------------------------- /ios/cnodejs/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | cnodejs 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 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UIViewControllerBasedStatusBarAppearance 40 | 41 | NSLocationWhenInUseUsageDescription 42 | 43 | NSAppTransportSecurity 44 | 45 | 46 | NSExceptionDomains 47 | 48 | localhost 49 | 50 | NSExceptionAllowsInsecureHTTPLoads 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/utils/request.js: -------------------------------------------------------------------------------- 1 | import { HOME_URL } from '../config'; 2 | 3 | function parseJSON(response) { 4 | return Promise.all([response, response.json()]) 5 | } 6 | 7 | function fetchHtml(response) { 8 | return Promise.all([response, response.text()]) 9 | } 10 | 11 | function checkStatus(response) { 12 | if (response.status >= 200 && response.status < 300) { 13 | return response; 14 | } 15 | 16 | const error = new Error(response.statusText); 17 | error.response = response; 18 | throw error; 19 | } 20 | 21 | /** 22 | * Requests a URL, returning a promise. 23 | * 24 | * @param {string} url The URL we want to request 25 | * @param {object} [options] The options we want to pass to "fetch" 26 | * @return {object} An object containing either "data" or "err" 27 | */ 28 | export function get(url, headers = {}) { 29 | if (!url.startsWith('https')) url = HOME_URL + url; 30 | const options = { 31 | method: 'GET', 32 | headers: headers 33 | } 34 | return fetch(url, options) 35 | .then(checkStatus) 36 | .then(parseJSON) 37 | .then(data => ({ data })) 38 | .catch(err => ({ err })); 39 | } 40 | 41 | export function post(url, body) { 42 | if (!url.startsWith('https')) url = HOME_URL + url; 43 | const options = { 44 | method: 'POST', 45 | headers: { 46 | 'Accept': 'application/json', 47 | 'Content-Type': 'application/json' 48 | }, 49 | body: JSON.stringify(body) 50 | } 51 | return fetch(url, options) 52 | .then(checkStatus) 53 | .then(parseJSON) 54 | .then(data => ({ data })) 55 | .catch(err => ({ err })); 56 | } 57 | 58 | export function requestHtml(url, headers = {}) { 59 | const options = { 60 | method: 'GET', 61 | headers: headers 62 | } 63 | return fetch(url, options) 64 | .then(checkStatus) 65 | .then(fetchHtml) 66 | .then(data => ({ data })) 67 | .catch(err => ({ err })); 68 | } 69 | -------------------------------------------------------------------------------- /src/pages/zone/screen/Dynamic.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | import { connect } from 'dva/mobile'; 3 | import { Tip } from '../../../components'; 4 | import Card from '../components/Card'; 5 | import { StyleSheet, View, Text, Button, Image, StatusBar, FlatList, Dimensions, TouchableOpacity } from 'react-native' 6 | 7 | const { width } = Dimensions.get('window'); 8 | 9 | class Dynamic extends PureComponent { 10 | constructor(props) { 11 | super(props) 12 | this.state = {} 13 | } 14 | 15 | static navigationOptions = ({ navigation }) => { 16 | const { title } = navigation.state.params; 17 | return { 18 | headerTitle: title, 19 | }; 20 | }; 21 | 22 | render() { 23 | const { navigate, state } = this.props.navigation; 24 | const { data = [] } = state.params 25 | 26 | return ( 27 | 28 | 29 | { 30 | data.length > 0 ? 31 | index} 36 | renderItem={({ item }) => } 37 | /> 38 | : 39 | } 40 | 41 | ); 42 | } 43 | } 44 | 45 | function mapStateToProps(state) { 46 | const { loading } = state.zone; 47 | return { loading }; 48 | } 49 | 50 | function mapDispatchToProps(dispatch) { 51 | return { 52 | query(params) { 53 | dispatch({ 54 | type: 'zone/query', 55 | payload: params, 56 | }); 57 | }, 58 | } 59 | } 60 | 61 | 62 | const styles = StyleSheet.create({ 63 | container: { 64 | flex: 1, 65 | backgroundColor: '#F8F8F8', 66 | } 67 | }); 68 | 69 | export default connect(mapStateToProps, mapDispatchToProps)(Dynamic); 70 | -------------------------------------------------------------------------------- /src/pages/notice/screen/Read.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | import { connect } from 'dva/mobile'; 3 | import { Tip } from '../../../components'; 4 | import Message from '../components/Message'; 5 | import { StyleSheet, View, Text, Button, Image, StatusBar, FlatList, Dimensions, TouchableOpacity } from 'react-native' 6 | 7 | const { width } = Dimensions.get('window'); 8 | 9 | class Read extends PureComponent { 10 | constructor(props) { 11 | super(props) 12 | this.state = {} 13 | } 14 | 15 | static navigationOptions = ({ navigation }) => { 16 | const { state, setParams } = navigation; 17 | return { 18 | headerTitle: '已读消息', 19 | }; 20 | }; 21 | 22 | render() { 23 | const { messages } = this.props.navigation.state.params; 24 | const { loading } = this.props 25 | const { navigate } = this.props.navigation; 26 | 27 | return ( 28 | 29 | 30 | { 31 | messages.length > 0 ? 32 | index} 37 | renderItem={({ item }) => } 38 | /> 39 | : 40 | } 41 | 42 | ); 43 | } 44 | } 45 | 46 | function mapStateToProps(state) { 47 | const { loading } = state.notice; 48 | return { loading }; 49 | } 50 | 51 | function mapDispatchToProps(dispatch) { 52 | return { 53 | query(params) { 54 | dispatch({ 55 | type: 'notice/query', 56 | payload: params, 57 | }); 58 | }, 59 | } 60 | } 61 | 62 | const styles = StyleSheet.create({ 63 | container: { 64 | flex: 1, 65 | backgroundColor: '#F8F8F8', 66 | }, 67 | }); 68 | 69 | export default connect(mapStateToProps, mapDispatchToProps)(Read); 70 | -------------------------------------------------------------------------------- /src/pages/zone/components/Card.js: -------------------------------------------------------------------------------- 1 | 2 | import React from 'react' 3 | import { StyleSheet, View, Image, Text, TouchableOpacity } from 'react-native' 4 | 5 | function Card({ item, navigate }) { 6 | 7 | return ( 8 | { navigate('Detail', { topic_id: item.id }) }}> 9 | 10 | 11 | {item.title} 12 | 13 | 14 | 15 | {item.last_reply_at} 16 | 17 | 18 | {item.author.loginname} 19 | 20 | 21 | 22 | 23 | ) 24 | } 25 | 26 | const styles = StyleSheet.create({ 27 | list: { 28 | padding: 20, 29 | backgroundColor: '#FFFFFF', 30 | borderBottomWidth: 1, 31 | borderColor: '#F0F0F0' 32 | }, 33 | 34 | header: { 35 | flex: 1, 36 | flexWrap: 'wrap', 37 | alignItems: 'center', 38 | flexDirection: 'row' 39 | }, 40 | 41 | h3: { 42 | flex: 1, 43 | overflow: 'hidden', 44 | fontSize: 16, 45 | fontWeight: 'bold', 46 | }, 47 | 48 | content: { 49 | flex: 1, 50 | paddingTop: 10, 51 | alignItems: 'center', 52 | flexDirection: 'row' 53 | }, 54 | 55 | avatar: { 56 | width: 40, 57 | height: 40, 58 | borderRadius: 20, 59 | marginRight: 10, 60 | }, 61 | 62 | timeView: { 63 | flex: 2, 64 | padding: 3, 65 | borderRadius: 3, 66 | marginRight: 10, 67 | backgroundColor: '#4B8CE2', 68 | }, 69 | 70 | p: { 71 | flex: 8, 72 | padding: 3, 73 | }, 74 | 75 | name: { 76 | color: '#999', 77 | fontSize: 12, 78 | }, 79 | 80 | time: { 81 | color: '#FFFFFF', 82 | textAlign: 'center', 83 | fontSize: 12, 84 | }, 85 | }); 86 | 87 | export default Card 88 | -------------------------------------------------------------------------------- /src/pages/publish/model.js: -------------------------------------------------------------------------------- 1 | import * as service from './service'; 2 | 3 | export default { 4 | namespace: 'publish', 5 | state: { 6 | topic_id: '', 7 | tab: 'dev', 8 | data: {}, 9 | title: '', 10 | content: '', 11 | loading: false, 12 | }, 13 | effects: { 14 | *create({ payload = {} }, { call, put }) { 15 | const { content, title, tab, accesstoken } = payload 16 | yield put({ type: 'loading', payload: true }); 17 | const { data, err } = yield call(service.createTopic, payload); 18 | yield put({ type: 'loading', payload: false }); 19 | if (err) return console.log(err) 20 | yield put({ type: 'create/success', payload: data }); 21 | }, 22 | *update({ payload = {} }, { call, put }) { 23 | const { content, title, tab, accesstoken, topic_id } = payload 24 | yield put({ type: 'loading', payload: true }); 25 | const { data, err } = yield call(service.updateTopic, payload); 26 | yield put({ type: 'loading', payload: false }); 27 | if (err) return console.log(err) 28 | yield put({ type: 'update/success', payload: data }); 29 | }, 30 | }, 31 | reducers: { 32 | 'create/success'(state, { payload }) { 33 | const [, data] = payload 34 | const { topic_id } = data 35 | return { ...state, topic_id }; 36 | }, 37 | 'update/success'(state, { payload }) { 38 | const [, data] = payload 39 | const { topic_id } = data 40 | return { ...state, topic_id }; 41 | }, 42 | 'tab'(state, { payload: data }) { 43 | return { ...state, tab: data }; 44 | }, 45 | 'title'(state, { payload: data }) { 46 | return { ...state, title: data }; 47 | }, 48 | 'content'(state, { payload: data }) { 49 | return { ...state, content: data }; 50 | }, 51 | 'loading'(state, { payload: data }) { 52 | return { ...state, loading: data }; 53 | }, 54 | 'clean'(state, { payload: data }) { 55 | return { ...state, topic_id: '' }; 56 | }, 57 | }, 58 | subscriptions: {}, 59 | }; 60 | -------------------------------------------------------------------------------- /src/pages/publish/components/Content.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { connect } from 'dva/mobile'; 3 | import { StyleSheet, Text, View, Image, TextInput, Modal, Dimensions, TouchableOpacity } from 'react-native'; 4 | 5 | class Content extends Component { 6 | constructor(props) { 7 | super(props); 8 | } 9 | 10 | componentDidMount() { 11 | const { content = '' } = this.props.data 12 | this.props.setContent(content) 13 | } 14 | 15 | render() { 16 | const { tab, content } = this.props 17 | const { height } = Dimensions.get('window'); 18 | const textareaHeight = height - 64 - 74 - 35 - 260 19 | 20 | return ( 21 | 22 | { this.props.setContent(content) }} 29 | /> 30 | 31 | ); 32 | } 33 | } 34 | 35 | function mapStateToProps(state) { 36 | const { content } = state.publish; 37 | const { data } = state.detail; 38 | return { data, content }; 39 | } 40 | 41 | function mapDispatchToProps(dispatch) { 42 | return { 43 | setContent(params) { 44 | dispatch({ 45 | type: 'publish/content', 46 | payload: params, 47 | }); 48 | }, 49 | } 50 | } 51 | 52 | const styles = StyleSheet.create({ 53 | content: { 54 | borderRadius: 5, 55 | borderWidth: 1, 56 | margin: 15, 57 | marginBottom: 0, 58 | borderColor: '#FFFFFF', 59 | justifyContent: 'center', 60 | backgroundColor: '#F8F8F8', 61 | }, 62 | 63 | textarea: { 64 | padding: 0, 65 | textAlign:'left', 66 | textAlignVertical:'top', 67 | fontSize: 16, 68 | marginTop: 10, 69 | marginBottom: 10, 70 | marginLeft: 15, 71 | marginRight: 15, 72 | } 73 | }); 74 | 75 | export default connect(mapStateToProps, mapDispatchToProps)(Content); -------------------------------------------------------------------------------- /src/pages/publish/components/Option.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { connect } from 'dva/mobile'; 3 | import { StyleSheet, Text, View, Image, TextInput, Dimensions, TouchableOpacity } from 'react-native'; 4 | 5 | class Option extends Component { 6 | constructor(props) { 7 | super(props); 8 | } 9 | 10 | _onPress = () => { 11 | const { content, title, tab, accesstoken, edit, data } = this.props 12 | let params = {} 13 | if (edit) { 14 | params = { content, title, tab, accesstoken, topic_id: data.id } 15 | this.props.update(params) 16 | } else { 17 | params = { content, title, tab, accesstoken } 18 | this.props.create(params) 19 | } 20 | } 21 | 22 | render() { 23 | return ( 24 | 25 | { this._onPress() }}> 26 | 27 | 28 | 29 | ); 30 | } 31 | } 32 | 33 | function mapStateToProps(state) { 34 | const { tab, content, title } = state.publish; 35 | const { data } = state.detail; 36 | const { accesstoken } = state.home 37 | return { tab, data, content, title, accesstoken }; 38 | } 39 | 40 | function mapDispatchToProps(dispatch) { 41 | return { 42 | create(params) { 43 | dispatch({ 44 | type: 'publish/create', 45 | payload: params, 46 | }); 47 | }, 48 | update(params) { 49 | dispatch({ 50 | type: 'publish/update', 51 | payload: params, 52 | }); 53 | }, 54 | } 55 | } 56 | 57 | const styles = StyleSheet.create({ 58 | headerRight: { 59 | flex: 1, 60 | flexDirection: 'row', 61 | alignItems: 'center' 62 | }, 63 | 64 | headerTouch: { 65 | height: 30 66 | }, 67 | 68 | headerBtn: { 69 | flex: 1, 70 | width: 30, 71 | height: 30, 72 | marginRight: 10 73 | }, 74 | }); 75 | 76 | export default connect(mapStateToProps, mapDispatchToProps)(Option); -------------------------------------------------------------------------------- /src/pages/zone/screen/Collect.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | import { connect } from 'dva/mobile'; 3 | import { Tip } from '../../../components'; 4 | import Card from '../components/Card'; 5 | import { StyleSheet, View, Text, Button, Image, StatusBar, FlatList, Dimensions, TouchableOpacity } from 'react-native' 6 | 7 | const { width } = Dimensions.get('window'); 8 | 9 | class Collect extends PureComponent { 10 | constructor(props) { 11 | super(props) 12 | this.state = {} 13 | } 14 | 15 | static navigationOptions = ({ navigation }) => { 16 | const { state, setParams } = navigation; 17 | return { 18 | headerTitle: '话题收藏', 19 | }; 20 | }; 21 | 22 | componentDidMount() { 23 | const { params } = this.props.navigation.state; 24 | this.props.query(params) 25 | } 26 | 27 | render() { 28 | const { collects, loading } = this.props 29 | const { navigate } = this.props.navigation; 30 | const { params } = this.props.navigation.state; 31 | 32 | return ( 33 | 34 | 35 | { 36 | collects.length > 0 ? 37 | index} 42 | renderItem={({ item }) => } 43 | onRefresh={() => { this.props.query(params) }} 44 | refreshing={loading} 45 | /> 46 | : 47 | } 48 | 49 | ); 50 | } 51 | } 52 | 53 | function mapStateToProps(state) { 54 | const { collects, loading } = state.zone; 55 | return { collects, loading }; 56 | } 57 | 58 | function mapDispatchToProps(dispatch) { 59 | return { 60 | query(params) { 61 | dispatch({ 62 | type: 'zone/collects', 63 | payload: params, 64 | }); 65 | }, 66 | } 67 | } 68 | 69 | 70 | const styles = StyleSheet.create({ 71 | container: { 72 | flex: 1, 73 | backgroundColor: '#F8F8F8', 74 | } 75 | }); 76 | 77 | export default connect(mapStateToProps, mapDispatchToProps)(Collect); 78 | -------------------------------------------------------------------------------- /src/pages/publish/index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react' 2 | import { connect } from 'dva/mobile' 3 | import Title from './components/Title' 4 | import Option from './components/Option' 5 | import Content from './components/Content' 6 | import { StyleSheet, View, ScrollView, Text, TextInput, Image, Modal, StatusBar, Dimensions, TouchableOpacity } from 'react-native' 7 | 8 | class Publish extends PureComponent { 9 | constructor(props) { 10 | super(props) 11 | } 12 | 13 | static navigationOptions = ({ navigation }) => { 14 | const { state, setParams, navigate } = navigation 15 | const { edit } = state.params ? state.params : {} 16 | return { 17 | headerTitle: edit ? '编辑话题' : '新建话题', 18 | headerRight: (