├── .watchmanconfig
├── App
├── I18n
│ ├── af.json
│ ├── am.json
│ ├── ar.json
│ ├── bg.json
│ ├── ca.json
│ ├── cs.json
│ ├── da.json
│ ├── de.json
│ ├── el.json
│ ├── es.json
│ ├── et.json
│ ├── fi.json
│ ├── he.json
│ ├── hi.json
│ ├── hr.json
│ ├── hu.json
│ ├── id.json
│ ├── it.json
│ ├── ja.json
│ ├── ko.json
│ ├── lt.json
│ ├── lv.json
│ ├── ms.json
│ ├── nb.json
│ ├── nl.json
│ ├── no.json
│ ├── pl.json
│ ├── pt.json
│ ├── ro.json
│ ├── ru.json
│ ├── sk.json
│ ├── sl.json
│ ├── sr.json
│ ├── sv.json
│ ├── sw.json
│ ├── th.json
│ ├── tr.json
│ ├── uk.json
│ ├── vi.json
│ ├── zh.json
│ ├── zu.json
│ ├── fil.json
│ ├── fr.json
│ ├── README.md
│ └── english.json
├── Containers
│ ├── ContactTest.js
│ ├── Styles
│ │ ├── README.md
│ │ ├── DrawerContentStyle.js
│ │ ├── APITestingScreenStyle.js
│ │ ├── AllComponentsScreenStyle.js
│ │ ├── PresentationScreenStyle.js
│ │ ├── MapviewExampleStyle.js
│ │ ├── AddContactModalStyle.js
│ │ ├── RootContainerStyle.js
│ │ ├── ListviewExampleStyle.js
│ │ ├── UsageExamplesScreenStyle.js
│ │ ├── GroupListScreenStyle.js
│ │ ├── ListviewGridExampleStyle.js
│ │ ├── GroupMembersScreenStyle.js
│ │ ├── ThemeScreenStyle.js
│ │ └── DeviceInfoScreenStyle.js
│ ├── README.md
│ ├── RootContainer.js
│ ├── PresentationScreen.js
│ └── DrawerContent.js
├── Lib
│ ├── axios
│ │ ├── index.js
│ │ ├── component.json
│ │ ├── lib
│ │ │ ├── helpers
│ │ │ │ ├── bind.js
│ │ │ │ ├── README.md
│ │ │ │ ├── combineURLs.js
│ │ │ │ ├── normalizeHeaderName.js
│ │ │ │ ├── isAbsoluteURL.js
│ │ │ │ ├── spread.js
│ │ │ │ ├── deprecatedMethod.js
│ │ │ │ ├── parseHeaders.js
│ │ │ │ ├── btoa.js
│ │ │ │ ├── cookies.js
│ │ │ │ └── buildURL.js
│ │ │ ├── core
│ │ │ │ ├── README.md
│ │ │ │ ├── enhanceError.js
│ │ │ │ ├── createError.js
│ │ │ │ ├── transformData.js
│ │ │ │ ├── settle.js
│ │ │ │ ├── InterceptorManager.js
│ │ │ │ └── dispatchRequest.js
│ │ │ ├── adapters
│ │ │ │ └── README.md
│ │ │ ├── axios.js
│ │ │ └── defaults.js
│ │ ├── http_proxy.txt
│ │ ├── LICENSE
│ │ └── axios.d.ts
│ ├── README.md
│ ├── Utilities.js
│ ├── MapHelpers.js
│ ├── apisauce
│ │ └── package.json
│ ├── PlatformStyleSheet.js
│ └── WebIMConfig.js
├── Sdk
│ ├── index.js
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ └── emoji.js
│ └── gulpfile.js
├── Images
│ ├── BG.png
│ ├── ir.png
│ ├── chats.png
│ ├── chats@2x.png
│ ├── chats@3x.png
│ ├── default.png
│ ├── feedback.png
│ ├── iconAdd.png
│ ├── iconFile.png
│ ├── logout.png
│ ├── message.png
│ ├── settings.png
│ ├── tile_bg.png
│ ├── top_logo.png
│ ├── buttonCall.png
│ ├── buttonChat.png
│ ├── default@2x.png
│ ├── default@3x.png
│ ├── iconAdd@2x.png
│ ├── iconAdd@3x.png
│ ├── iconAudio.png
│ ├── iconCamera.png
│ ├── iconEmoji.png
│ ├── iconImage.png
│ ├── logoGreen.png
│ ├── logout@2x.png
│ ├── logout@3x.png
│ ├── message@2x.png
│ ├── message@3x.png
│ ├── buttonCall@2x.png
│ ├── buttonCall@3x.png
│ ├── buttonChat@2x.png
│ ├── buttonChat@3x.png
│ ├── buttonVideo.png
│ ├── feedback@2x.png
│ ├── feedback@3x.png
│ ├── groupDefault.png
│ ├── iconAudio@2x.png
│ ├── iconAudio@3x.png
│ ├── iconCamera@2x.png
│ ├── iconCamera@3x.png
│ ├── iconEmoji@2x.png
│ ├── iconEmoji@3x.png
│ ├── iconFile@2x.png
│ ├── iconFile@3x.png
│ ├── iconImage@2x.png
│ ├── iconImage@3x.png
│ ├── iconLocation.png
│ ├── ignite_logo.png
│ ├── logoGreen@2x.png
│ ├── logoGreen@3x.png
│ ├── requestsIcon.png
│ ├── settings@2x.png
│ ├── settings@3x.png
│ ├── top_logo@2x.png
│ ├── top_logo@3x.png
│ ├── buttonVideo@2x.png
│ ├── buttonVideo@3x.png
│ ├── contactsActive.png
│ ├── groupDefault@2x.png
│ ├── groupDefault@3x.png
│ ├── iconEmojiActive.png
│ ├── iconLocation@2x.png
│ ├── iconLocation@3x.png
│ ├── invitationsIcon.png
│ ├── requestsIcon@2x.png
│ ├── requestsIcon@3x.png
│ ├── contactsActive@2x.png
│ ├── contactsActive@3x.png
│ ├── iconEmojiActive@2x.png
│ ├── iconEmojiActive@3x.png
│ ├── invitationsIcon@2x.png
│ ├── invitationsIcon@3x.png
│ ├── chatsActiveNotification.png
│ ├── chatsActiveNotification@2x.png
│ └── chatsActiveNotification@3x.png
├── Components
│ ├── README.md
│ ├── Styles
│ │ ├── README.md
│ │ ├── MapCalloutStyle.js
│ │ ├── DrawerButtonStyles.js
│ │ ├── ButtonStyle.js
│ │ ├── FullButtonStyle.js
│ │ ├── RoundedButtonStyle.js
│ │ ├── AlertMessageStyle.js
│ │ ├── CustomNavBarStyle.js
│ │ ├── ModalHeaderStyle.js
│ │ ├── InputStyle.js
│ │ └── InfoNavBarStyle.js
│ ├── TabIcon.js
│ ├── CustomNavBar.js
│ ├── DrawerButton.js
│ ├── FullButton.js
│ ├── RoundedButton.js
│ ├── ModalHeader.js
│ ├── Button.js
│ ├── MapCallout.js
│ ├── AlertMessage.js
│ ├── Base.js
│ ├── InfoNavBar.js
│ └── Row.js
├── Themes
│ ├── README.md
│ ├── index.js
│ ├── Metrics.js
│ ├── Fonts.js
│ ├── Images.js
│ ├── Colors.js
│ └── ApplicationStyles.js
├── Config
│ ├── AppConfig.js
│ ├── DebugSettings.js
│ ├── README.md
│ ├── index.js
│ ├── ReduxPersist.js
│ ├── PushConfig.js
│ └── ReactotronConfig.js
├── Navigation
│ ├── Styles
│ │ ├── NavigationDrawerStyle.js
│ │ ├── NavItemsStyle.js
│ │ └── NavigationContainerStyle.js
│ └── NavItems.js
├── Redux
│ ├── StartupRedux.js
│ ├── ContactsScreenRedux.js
│ ├── CommonRedux.js
│ ├── ContactInfoScreenRedux.js
│ ├── DemoRedux.js
│ ├── GroupMemberRedux.js
│ ├── TemperatureRedux.js
│ ├── index.js
│ ├── GroupRedux.js
│ ├── SubscribeRedux.js
│ └── CreateStore.js
├── Fixtures
│ ├── README.md
│ ├── boise.json
│ └── toronto.json
├── Transforms
│ ├── ConvertFromKelvin.js
│ └── README.md
├── Sagas
│ ├── LoginSagas.js
│ ├── StartupSagas.js
│ ├── TemperatureSagas.js
│ └── index.js
└── Services
│ ├── FixtureApi.js
│ ├── ExamplesRegistry.js
│ ├── RehydrationServices.js
│ ├── ImmutablePersistenceTransform.js
│ └── Api.js
├── .travis.yml
├── .env
├── main.jsbundle.meta
├── ios
├── main.jsbundle.meta
├── app
│ ├── main.jsbundle.meta
│ ├── Images.xcassets
│ │ ├── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ ├── Icon-76.png
│ │ │ ├── Icon-60@2x.png
│ │ │ ├── Icon-60@3x.png
│ │ │ ├── Icon-76@2x.png
│ │ │ ├── Icon-Small.png
│ │ │ ├── Icon-83.5@2x.png
│ │ │ ├── Icon-Small-60.png
│ │ │ ├── Icon-Small@2x.png
│ │ │ ├── Icon-Small@3x.png
│ │ │ ├── Icon-Small-40@2x.png
│ │ │ ├── Icon-Small-60@2x.png
│ │ │ └── Icon-Small-60@3x.png
│ │ └── LaunchImage.launchimage
│ │ │ ├── Splash_iphone4.png
│ │ │ ├── Splash_iphone5.png
│ │ │ ├── Splash_iphone6.png
│ │ │ ├── Splash_iphone6p.png
│ │ │ └── Contents.json
│ ├── AppDelegate.h
│ ├── main.m
│ └── AppDelegate.m
├── app.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ └── lwz.xcuserdatad
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcuserdata
│ │ └── lwz.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── appTests
│ ├── Info.plist
│ └── appTests.m
├── android
├── app
│ ├── hyphenate.keystore
│ ├── 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
│ │ │ ├── assets
│ │ │ └── fonts
│ │ │ │ ├── Entypo.ttf
│ │ │ │ ├── Zocial.ttf
│ │ │ │ ├── EvilIcons.ttf
│ │ │ │ ├── Foundation.ttf
│ │ │ │ ├── Ionicons.ttf
│ │ │ │ ├── Octicons.ttf
│ │ │ │ ├── FontAwesome.ttf
│ │ │ │ └── MaterialIcons.ttf
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── app
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── MainApplication.java
│ │ │ └── AndroidManifest.xml
│ ├── my-release-key.keystore
│ └── BUCK
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── keystores
│ ├── debug.keystore.properties
│ └── BUCK
├── build.gradle
├── app.iml
├── gradle.properties
└── settings.gradle
├── .buckconfig
├── .babelrc
├── .ignite
├── .editorconfig
├── __tests__
├── index.ios.js
└── index.android.js
├── fastlane
├── Matchfile
└── Appfile
├── index.android.js
├── index.ios.js
├── .gitignore
├── Tests
├── Services
│ └── FixtureAPITest.js
├── Sagas
│ ├── StartupSagaTest.js
│ ├── LoginSagaTest.js
│ └── TemperatureSagaTest.js
├── Reducers
│ ├── LoginReducerTest.js
│ └── TemperatureReducerTest.js
├── Components
│ ├── DrawerButtonTest.js
│ ├── FullButtonTest.js
│ ├── RoundedButtonTest.js
│ └── AlertMessageTest.js
└── Setup.js
├── CHANGELOG.md
├── .tmp
└── reactNativeBuild
│ └── debuggerWorker.js
└── .flowconfig
/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/App/I18n/af.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/am.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/ar.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/bg.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/ca.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/cs.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/da.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/de.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/el.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/es.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/et.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/fi.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/he.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/hi.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/hr.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/hu.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/id.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/it.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/ja.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/ko.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/lt.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/lv.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/ms.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/nb.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/nl.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/no.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/pl.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/pt.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/ro.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/ru.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/sk.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/sl.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/sr.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/sv.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/sw.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/th.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/tr.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/uk.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/vi.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/zh.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/zu.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/App/I18n/fil.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
--------------------------------------------------------------------------------
/App/Containers/ContactTest.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/App/Lib/axios/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./lib/axios');
--------------------------------------------------------------------------------
/App/Sdk/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./src/connection')
2 |
--------------------------------------------------------------------------------
/.env:
--------------------------------------------------------------------------------
1 | # Your secrets go here e.g.
2 | # MY_SECRET_API_KEY=tacosareawesome
--------------------------------------------------------------------------------
/App/Images/BG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/BG.png
--------------------------------------------------------------------------------
/App/Images/ir.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/ir.png
--------------------------------------------------------------------------------
/main.jsbundle.meta:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/main.jsbundle.meta
--------------------------------------------------------------------------------
/App/Components/README.md:
--------------------------------------------------------------------------------
1 | ### Copmonents Folder
2 | All components are stored and organized here
3 |
--------------------------------------------------------------------------------
/App/Images/chats.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/chats.png
--------------------------------------------------------------------------------
/App/Components/Styles/README.md:
--------------------------------------------------------------------------------
1 | ### Styles Folder
2 | Component styles are separated from functionality.
3 |
--------------------------------------------------------------------------------
/App/Containers/Styles/README.md:
--------------------------------------------------------------------------------
1 | ### Styles Folder
2 | Container styles are separated from functionality.
3 |
--------------------------------------------------------------------------------
/App/Images/chats@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/chats@2x.png
--------------------------------------------------------------------------------
/App/Images/chats@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/chats@3x.png
--------------------------------------------------------------------------------
/App/Images/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/default.png
--------------------------------------------------------------------------------
/App/Images/feedback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/feedback.png
--------------------------------------------------------------------------------
/App/Images/iconAdd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconAdd.png
--------------------------------------------------------------------------------
/App/Images/iconFile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconFile.png
--------------------------------------------------------------------------------
/App/Images/logout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/logout.png
--------------------------------------------------------------------------------
/App/Images/message.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/message.png
--------------------------------------------------------------------------------
/App/Images/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/settings.png
--------------------------------------------------------------------------------
/App/Images/tile_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/tile_bg.png
--------------------------------------------------------------------------------
/App/Images/top_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/top_logo.png
--------------------------------------------------------------------------------
/ios/main.jsbundle.meta:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/main.jsbundle.meta
--------------------------------------------------------------------------------
/App/Images/buttonCall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/buttonCall.png
--------------------------------------------------------------------------------
/App/Images/buttonChat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/buttonChat.png
--------------------------------------------------------------------------------
/App/Images/default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/default@2x.png
--------------------------------------------------------------------------------
/App/Images/default@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/default@3x.png
--------------------------------------------------------------------------------
/App/Images/iconAdd@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconAdd@2x.png
--------------------------------------------------------------------------------
/App/Images/iconAdd@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconAdd@3x.png
--------------------------------------------------------------------------------
/App/Images/iconAudio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconAudio.png
--------------------------------------------------------------------------------
/App/Images/iconCamera.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconCamera.png
--------------------------------------------------------------------------------
/App/Images/iconEmoji.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconEmoji.png
--------------------------------------------------------------------------------
/App/Images/iconImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconImage.png
--------------------------------------------------------------------------------
/App/Images/logoGreen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/logoGreen.png
--------------------------------------------------------------------------------
/App/Images/logout@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/logout@2x.png
--------------------------------------------------------------------------------
/App/Images/logout@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/logout@3x.png
--------------------------------------------------------------------------------
/App/Images/message@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/message@2x.png
--------------------------------------------------------------------------------
/App/Images/message@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/message@3x.png
--------------------------------------------------------------------------------
/App/Images/buttonCall@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/buttonCall@2x.png
--------------------------------------------------------------------------------
/App/Images/buttonCall@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/buttonCall@3x.png
--------------------------------------------------------------------------------
/App/Images/buttonChat@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/buttonChat@2x.png
--------------------------------------------------------------------------------
/App/Images/buttonChat@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/buttonChat@3x.png
--------------------------------------------------------------------------------
/App/Images/buttonVideo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/buttonVideo.png
--------------------------------------------------------------------------------
/App/Images/feedback@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/feedback@2x.png
--------------------------------------------------------------------------------
/App/Images/feedback@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/feedback@3x.png
--------------------------------------------------------------------------------
/App/Images/groupDefault.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/groupDefault.png
--------------------------------------------------------------------------------
/App/Images/iconAudio@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconAudio@2x.png
--------------------------------------------------------------------------------
/App/Images/iconAudio@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconAudio@3x.png
--------------------------------------------------------------------------------
/App/Images/iconCamera@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconCamera@2x.png
--------------------------------------------------------------------------------
/App/Images/iconCamera@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconCamera@3x.png
--------------------------------------------------------------------------------
/App/Images/iconEmoji@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconEmoji@2x.png
--------------------------------------------------------------------------------
/App/Images/iconEmoji@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconEmoji@3x.png
--------------------------------------------------------------------------------
/App/Images/iconFile@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconFile@2x.png
--------------------------------------------------------------------------------
/App/Images/iconFile@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconFile@3x.png
--------------------------------------------------------------------------------
/App/Images/iconImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconImage@2x.png
--------------------------------------------------------------------------------
/App/Images/iconImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconImage@3x.png
--------------------------------------------------------------------------------
/App/Images/iconLocation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconLocation.png
--------------------------------------------------------------------------------
/App/Images/ignite_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/ignite_logo.png
--------------------------------------------------------------------------------
/App/Images/logoGreen@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/logoGreen@2x.png
--------------------------------------------------------------------------------
/App/Images/logoGreen@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/logoGreen@3x.png
--------------------------------------------------------------------------------
/App/Images/requestsIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/requestsIcon.png
--------------------------------------------------------------------------------
/App/Images/settings@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/settings@2x.png
--------------------------------------------------------------------------------
/App/Images/settings@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/settings@3x.png
--------------------------------------------------------------------------------
/App/Images/top_logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/top_logo@2x.png
--------------------------------------------------------------------------------
/App/Images/top_logo@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/top_logo@3x.png
--------------------------------------------------------------------------------
/ios/app/main.jsbundle.meta:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/main.jsbundle.meta
--------------------------------------------------------------------------------
/App/Images/buttonVideo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/buttonVideo@2x.png
--------------------------------------------------------------------------------
/App/Images/buttonVideo@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/buttonVideo@3x.png
--------------------------------------------------------------------------------
/App/Images/contactsActive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/contactsActive.png
--------------------------------------------------------------------------------
/App/Images/groupDefault@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/groupDefault@2x.png
--------------------------------------------------------------------------------
/App/Images/groupDefault@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/groupDefault@3x.png
--------------------------------------------------------------------------------
/App/Images/iconEmojiActive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconEmojiActive.png
--------------------------------------------------------------------------------
/App/Images/iconLocation@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconLocation@2x.png
--------------------------------------------------------------------------------
/App/Images/iconLocation@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconLocation@3x.png
--------------------------------------------------------------------------------
/App/Images/invitationsIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/invitationsIcon.png
--------------------------------------------------------------------------------
/App/Images/requestsIcon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/requestsIcon@2x.png
--------------------------------------------------------------------------------
/App/Images/requestsIcon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/requestsIcon@3x.png
--------------------------------------------------------------------------------
/android/app/hyphenate.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/android/app/hyphenate.keystore
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/App/Images/contactsActive@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/contactsActive@2x.png
--------------------------------------------------------------------------------
/App/Images/contactsActive@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/contactsActive@3x.png
--------------------------------------------------------------------------------
/App/Images/iconEmojiActive@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconEmojiActive@2x.png
--------------------------------------------------------------------------------
/App/Images/iconEmojiActive@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/iconEmojiActive@3x.png
--------------------------------------------------------------------------------
/App/Images/invitationsIcon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/invitationsIcon@2x.png
--------------------------------------------------------------------------------
/App/Images/invitationsIcon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/invitationsIcon@3x.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Hyphenate JS
3 |
4 |
--------------------------------------------------------------------------------
/android/app/my-release-key.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/android/app/my-release-key.keystore
--------------------------------------------------------------------------------
/App/Images/chatsActiveNotification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/chatsActiveNotification.png
--------------------------------------------------------------------------------
/App/Images/chatsActiveNotification@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/chatsActiveNotification@2x.png
--------------------------------------------------------------------------------
/App/Images/chatsActiveNotification@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/App/Images/chatsActiveNotification@3x.png
--------------------------------------------------------------------------------
/App/Themes/README.md:
--------------------------------------------------------------------------------
1 | ### Themes Folder
2 | Application specific themes
3 | * Base Styles
4 | * Fonts
5 | * Metrics
6 | * Colors
7 |
8 | etc.
9 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/.buckconfig:
--------------------------------------------------------------------------------
1 |
2 | [android]
3 | target = Google Inc.:Google APIs:23
4 |
5 | [maven_repositories]
6 | central = https://repo1.maven.org/maven2
7 |
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Entypo.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/android/app/src/main/assets/fonts/Entypo.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Zocial.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/android/app/src/main/assets/fonts/Zocial.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/EvilIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/android/app/src/main/assets/fonts/EvilIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Foundation.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/android/app/src/main/assets/fonts/Foundation.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/android/app/src/main/assets/fonts/Ionicons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Octicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/android/app/src/main/assets/fonts/Octicons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/FontAwesome.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/android/app/src/main/assets/fonts/FontAwesome.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/MaterialIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/android/app/src/main/assets/fonts/MaterialIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/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/easemob/webim-react-native/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/easemob/webim-react-native/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "react-native"
4 | ],
5 | "env": {
6 | "development": {
7 | "sourceMaps": "inline"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/.ignite:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | igniteVersion: '1.11.0',
3 | reactNativeVersion: '0.36.0',
4 | options: {
5 | testing: 'ava'
6 | },
7 | plugins: {}
8 | }
9 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/AppIcon.appiconset/Icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/Images.xcassets/AppIcon.appiconset/Icon-76.png
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/AppIcon.appiconset/Icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/Images.xcassets/AppIcon.appiconset/Icon-Small.png
--------------------------------------------------------------------------------
/App/Config/AppConfig.js:
--------------------------------------------------------------------------------
1 | // Simple React Native specific changes
2 |
3 | export default {
4 | // font scaling override - RN default is on
5 | allowTextFontScaling: true
6 | }
7 |
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/AppIcon.appiconset/Icon-Small-60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/Images.xcassets/AppIcon.appiconset/Icon-Small-60.png
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/Images.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/AppIcon.appiconset/Icon-Small-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/Images.xcassets/AppIcon.appiconset/Icon-Small-60@2x.png
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/AppIcon.appiconset/Icon-Small-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/Images.xcassets/AppIcon.appiconset/Icon-Small-60@3x.png
--------------------------------------------------------------------------------
/android/keystores/BUCK:
--------------------------------------------------------------------------------
1 | keystore(
2 | name = 'debug',
3 | store = 'debug.keystore',
4 | properties = 'debug.keystore.properties',
5 | visibility = [
6 | 'PUBLIC',
7 | ],
8 | )
9 |
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/LaunchImage.launchimage/Splash_iphone4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/Images.xcassets/LaunchImage.launchimage/Splash_iphone4.png
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/LaunchImage.launchimage/Splash_iphone5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/Images.xcassets/LaunchImage.launchimage/Splash_iphone5.png
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/LaunchImage.launchimage/Splash_iphone6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/Images.xcassets/LaunchImage.launchimage/Splash_iphone6.png
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/LaunchImage.launchimage/Splash_iphone6p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easemob/webim-react-native/HEAD/ios/app/Images.xcassets/LaunchImage.launchimage/Splash_iphone6p.png
--------------------------------------------------------------------------------
/App/Containers/Styles/DrawerContentStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | export default {
4 | container: {
5 | flex: 1,
6 | padding: 20
7 | },
8 | logo: {
9 | alignSelf: 'center'
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/App/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
--------------------------------------------------------------------------------
/App/Config/DebugSettings.js:
--------------------------------------------------------------------------------
1 | const SETTINGS = {
2 | useFixtures: false,
3 | ezLogin: false,
4 | yellowBox: __DEV__,
5 | reduxLogging: __DEV__,
6 | includeExamples: __DEV__
7 | }
8 |
9 | export default SETTINGS
10 |
--------------------------------------------------------------------------------
/App/Components/Styles/MapCalloutStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { StyleSheet } from 'react-native'
4 |
5 | export default StyleSheet.create({
6 | callout: {
7 | position: 'relative',
8 | flex: 1
9 | }
10 | })
11 |
--------------------------------------------------------------------------------
/App/Config/README.md:
--------------------------------------------------------------------------------
1 | ### Config Folder
2 | All application specific configuration falls in this folder.
3 |
4 | `DebugSettings.js` is used for development-wide globals.
5 | `ReactotronConfig.js` is used for Reactotron client settings.
6 |
--------------------------------------------------------------------------------
/App/Containers/Styles/APITestingScreenStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { StyleSheet } from 'react-native'
4 | import { ApplicationStyles } from '../../Themes/'
5 |
6 | export default StyleSheet.create({
7 | ...ApplicationStyles.screen
8 | })
9 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/App/Lib/axios/component.json:
--------------------------------------------------------------------------------
1 | {"name":"axios","version":"0.9.1","description":"Promise based HTTP client for the browser and node.js","keywords":["xhr","http","ajax","promise","node"],"repo":{"type":"git","url":"https://github.com/mzabriskie/axios.git"},"license":"MIT"}
2 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | [*]
7 | charset = utf-8
8 | indent_style = space
9 | indent_size = 2
10 | end_of_line = lf
11 | insert_final_newline = true
12 | trim_trailing_whitespace = true
13 |
--------------------------------------------------------------------------------
/App/Navigation/Styles/NavigationDrawerStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import {Colors} from '../../Themes/'
4 |
5 | export default {
6 | drawer: {
7 | backgroundColor: Colors.transparent
8 | },
9 | main: {
10 | backgroundColor: Colors.snow
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/App/Components/Styles/DrawerButtonStyles.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { Metrics, Colors, Fonts } from '../../Themes'
4 |
5 | export default {
6 | text: {
7 | ...Fonts.style.h5,
8 | color: Colors.snow,
9 | marginVertical: Metrics.baseMargin
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ios/app.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Nov 21 11:50:05 CST 2016
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-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/App/Themes/index.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import Colors from './Colors'
4 | import Fonts from './Fonts'
5 | import Metrics from './Metrics'
6 | import Images from './Images'
7 | import ApplicationStyles from './ApplicationStyles'
8 |
9 | export { Colors, Fonts, Images, Metrics, ApplicationStyles }
10 |
--------------------------------------------------------------------------------
/App/Redux/StartupRedux.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { createActions } from 'reduxsauce'
4 |
5 | /* ------------- Types and Action Creators ------------- */
6 |
7 | const { Types, Creators } = createActions({
8 | startup: null
9 | })
10 |
11 | export const StartupTypes = Types
12 | export default Creators
13 |
--------------------------------------------------------------------------------
/App/Fixtures/README.md:
--------------------------------------------------------------------------------
1 | ### Fixtures folder
2 | All key API responses are housed here.
3 |
4 | These API responses can be used for several reasons. _E.G._:
5 | * To bypass logins when building any screen of the application
6 | * To quickly test API parsing in unit tests
7 | * To separate Network from Data concerns while coding
8 |
--------------------------------------------------------------------------------
/App/Containers/Styles/AllComponentsScreenStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { StyleSheet } from 'react-native'
4 | import { ApplicationStyles } from '../../Themes/'
5 |
6 | export default StyleSheet.create({
7 | ...ApplicationStyles.screen,
8 | groupContainer: {
9 | ...ApplicationStyles.groupContainer
10 | }
11 | })
12 |
--------------------------------------------------------------------------------
/App/Lib/axios/lib/helpers/bind.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function bind(fn, thisArg) {
4 | return function wrap() {
5 | var args = new Array(arguments.length);
6 | for (var i = 0; i < args.length; i++) {
7 | args[i] = arguments[i];
8 | }
9 | return fn.apply(thisArg, args);
10 | };
11 | };
12 |
--------------------------------------------------------------------------------
/__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 |
--------------------------------------------------------------------------------
/App/Navigation/Styles/NavItemsStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import {StyleSheet} from 'react-native'
4 | import { Metrics, Colors } from '../../Themes/'
5 |
6 | export default StyleSheet.create({
7 | navButtonLeft: {
8 | marginLeft: Metrics.baseMargin,
9 | backgroundColor: Colors.transparent,
10 | width: Metrics.icons.medium
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 |
--------------------------------------------------------------------------------
/App/Transforms/ConvertFromKelvin.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import I18n from 'react-native-i18n'
4 |
5 | export default (kelvin: number) => {
6 | const celcius = kelvin - 273.15
7 | const farenheit = (celcius * 1.8000) + 32
8 |
9 | if (I18n.t('tempIndicator') === 'F') {
10 | return Math.round(farenheit)
11 | } else {
12 | return Math.round(celcius)
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/App/Lib/axios/lib/core/README.md:
--------------------------------------------------------------------------------
1 | # axios // core
2 |
3 | The modules found in `core/` should be modules that are specific to the domain logic of axios. These modules would most likely not make sense to be consumed outside of the axios module, as their logic is too specific. Some examples of core modules are:
4 |
5 | - Dispatching requests
6 | - Managing interceptors
7 | - Handling config
8 |
--------------------------------------------------------------------------------
/App/Lib/axios/lib/helpers/README.md:
--------------------------------------------------------------------------------
1 | # axios // helpers
2 |
3 | The modules found in `helpers/` should be generic modules that are _not_ specific to the domain logic of axios. These modules could theoretically be published to npm on their own and consumed by other modules or apps. Some examples of generic modules are things like:
4 |
5 | - Browser polyfills
6 | - Managing cookies
7 | - Parsing HTTP headers
8 |
--------------------------------------------------------------------------------
/fastlane/Matchfile:
--------------------------------------------------------------------------------
1 | # git_url "git@github.com:infinitered/IgniteCerts.git"
2 |
3 | type "development" # The default type, can be: appstore, adhoc or development
4 |
5 | # app_identifier "tools.fastlane.app"
6 | # username "user@fastlane.tools" # Your Apple Developer Portal username
7 |
8 | # For all available options run `match --help`
9 | # Remove the # in the beginning of the line to enable the other options
10 |
--------------------------------------------------------------------------------
/App/Lib/axios/lib/helpers/combineURLs.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Creates a new URL by combining the specified URLs
5 | *
6 | * @param {string} baseURL The base URL
7 | * @param {string} relativeURL The relative URL
8 | * @returns {string} The combined URL
9 | */
10 | module.exports = function combineURLs(baseURL, relativeURL) {
11 | return baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '');
12 | };
13 |
--------------------------------------------------------------------------------
/App/Sagas/LoginSagas.js:
--------------------------------------------------------------------------------
1 | import { put } from 'redux-saga/effects'
2 | import LoginActions from '../Redux/LoginRedux'
3 |
4 | // attempts to login
5 | export function * login ({ username, password }) {
6 | if (password === '') {
7 | // dispatch failure
8 | yield put(LoginActions.loginFailure('WRONG'))
9 | } else {
10 | // dispatch successful logins
11 | yield put(LoginActions.loginSuccess(username))
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/App/Containers/Styles/PresentationScreenStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { StyleSheet } from 'react-native'
4 | import { Metrics, ApplicationStyles } from '../../Themes/'
5 |
6 | export default StyleSheet.create({
7 | ...ApplicationStyles.screen,
8 | logo: {
9 | height: Metrics.images.logo,
10 | width: Metrics.images.logo,
11 | resizeMode: 'contain'
12 | },
13 | centered: {
14 | alignItems: 'center'
15 | }
16 | })
17 |
--------------------------------------------------------------------------------
/App/Lib/axios/lib/helpers/normalizeHeaderName.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('../utils');
4 |
5 | module.exports = function normalizeHeaderName(headers, normalizedName) {
6 | utils.forEach(headers, function processHeader(value, name) {
7 | if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {
8 | headers[normalizedName] = value;
9 | delete headers[name];
10 | }
11 | });
12 | };
13 |
--------------------------------------------------------------------------------
/index.android.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import './App/Config/ReactotronConfig'
4 | import ReactNative, { AppRegistry, View } from 'react-native'
5 |
6 | // 兼容 0.39 版本的支持
7 | ReactNative.ViewPropTypes || ( ReactNative.ViewPropTypes = View.propTypes );
8 | ReactNative.BackHandler || ( ReactNative.BackHandler = ReactNative.BackAndroid );
9 |
10 | let App = require( './App/Containers/App' ).default;
11 |
12 | AppRegistry.registerComponent('app', () => App)
13 |
--------------------------------------------------------------------------------
/index.ios.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import './App/Config/ReactotronConfig'
4 | import ReactNative, { AppRegistry, View } from 'react-native'
5 |
6 | // 兼容 0.39 版本的支持
7 | ReactNative.ViewPropTypes || ( ReactNative.ViewPropTypes = View.propTypes );
8 | ReactNative.BackHandler || ( ReactNative.BackHandler = ReactNative.BackAndroid );
9 |
10 | let App = require( './App/Containers/App' ).default;
11 |
12 | AppRegistry.registerComponent('app', () => App)
13 |
--------------------------------------------------------------------------------
/App/Services/FixtureApi.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | export default {
4 | // Functions return fixtures
5 | getCity: (city: string) => {
6 | // This fixture only supports Boise or else returns toronto
7 | const boiseData = require('../Fixtures/boise.json')
8 | const torontoData = require('../Fixtures/toronto.json')
9 | return {
10 | ok: true,
11 | data: city.toLowerCase() === 'boise' ? boiseData : torontoData
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/app/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.app;
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 "app";
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/App/Lib/README.md:
--------------------------------------------------------------------------------
1 | # Lib
2 |
3 | At first glance, this could appear to be a "miscellaneous" folder, but we recommend that you treat this as proving ground for components that could be reuseable outside your project.
4 |
5 | Maybe you're writing a set of utilities that you could use outside your project, but they're not quite ready or battle tested. This folder would be a great place to put them. They ideally be pure functions have no dependencies on other things in your App folder.
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | /.project
4 | .idea/*
5 | *.swp
6 | demo/javascript/dist/demo.js
7 | demo/javascript/dist/debug.js
8 | demo/javascript/dist/webim.config.js
9 | App/Sdk/dist/websdk-*.js
10 | webrtc/dist/webrtc-1.0.0.js
11 | publish/*
12 | /webrtc/dist/webrtc-1.0.0.js
13 | android/.gradle
14 | android/app/build
15 | android/build
16 | android/local.properties
17 | yarn-error.log
18 | ios/build
19 | npm-debug.log
20 | ios/app.xcodeproj/project.xcworkspace/xcuserdata/lwz.xcuserdatad
21 |
--------------------------------------------------------------------------------
/App/Containers/Styles/MapviewExampleStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { StyleSheet } from 'react-native'
4 | import { ApplicationStyles } from '../../Themes/'
5 |
6 | export default StyleSheet.create({
7 | ...ApplicationStyles.screen,
8 | container: {
9 | flex: 1,
10 | justifyContent: 'flex-end',
11 | alignItems: 'center'
12 | },
13 | map: {
14 | // For Android :/
15 | position: 'absolute',
16 | top: 0,
17 | left: 0,
18 | right: 0,
19 | bottom: 0
20 | }
21 | })
22 |
--------------------------------------------------------------------------------
/ios/app/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 |
--------------------------------------------------------------------------------
/Tests/Services/FixtureAPITest.js:
--------------------------------------------------------------------------------
1 | import test from 'ava'
2 | import API from '../../App/Services/Api'
3 | import FixtureAPI from '../../App/Services/FixtureApi'
4 | import R from 'ramda'
5 |
6 | test('All fixtures map to actual API', (t) => {
7 | const fixtureKeys = R.keys(FixtureAPI).sort()
8 | const apiKeys = R.keys(API.create())
9 |
10 | const intersection = R.intersection(fixtureKeys, apiKeys).sort()
11 |
12 | // There is no difference between the intersection and all fixtures
13 | t.true(R.equals(fixtureKeys, intersection))
14 | })
15 |
--------------------------------------------------------------------------------
/App/Config/index.js:
--------------------------------------------------------------------------------
1 | import { Text } from 'react-native'
2 | import DebugSettings from './DebugSettings'
3 | import AppConfig from './AppConfig'
4 |
5 | export default () => {
6 | if (__DEV__) {
7 | // If ReactNative's yellow box warnings are too much, it is possible to turn
8 | // it off, but the healthier approach is to fix the warnings. =)
9 | console.disableYellowBox = !DebugSettings.yellowBox
10 | }
11 |
12 | // Allow/disallow font-scaling in app
13 | Text.defaultProps.allowFontScaling = AppConfig.allowTextFontScaling
14 | }
15 |
--------------------------------------------------------------------------------
/App/Components/Styles/ButtonStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { StyleSheet } from 'react-native'
4 | import { Fonts, Colors } from '../../Themes/'
5 |
6 | export default StyleSheet.create({
7 | button: {
8 | marginVertical: 5,
9 | borderRadius: 3,
10 | backgroundColor: Colors.button,
11 | paddingVertical: 10,
12 | paddingHorizontal: 20,
13 | height: 40,
14 | },
15 | buttonText: {
16 | textAlign: 'center',
17 | color: Colors.snow,
18 | fontSize: Fonts.size.medium,
19 | fontFamily: Fonts.type.bold
20 | }
21 | })
22 |
--------------------------------------------------------------------------------
/ios/app/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 |
--------------------------------------------------------------------------------
/App/Sagas/StartupSagas.js:
--------------------------------------------------------------------------------
1 | import { put, select } from 'redux-saga/effects'
2 | import TemperatureActions from '../Redux/TemperatureRedux'
3 | import { is } from 'ramda'
4 |
5 | // exported to make available for tests
6 | export const selectTemperature = (state) => state.temperature.temperature
7 |
8 | // process STARTUP actions
9 | export function * startup (action) {
10 | const temp = yield select(selectTemperature)
11 | // only fetch new temps when we don't have one yet
12 | if (!is(Number, temp)) {
13 | yield put(TemperatureActions.temperatureRequest('San Francisco'))
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/App/Components/Styles/FullButtonStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { StyleSheet } from 'react-native'
4 | import { Fonts, Colors } from '../../Themes/'
5 |
6 | export default StyleSheet.create({
7 | button: {
8 | marginVertical: 5,
9 | borderTopColor: Colors.fire,
10 | borderBottomColor: Colors.bloodOrange,
11 | borderTopWidth: 1,
12 | borderBottomWidth: 1,
13 | backgroundColor: Colors.ember
14 | },
15 | buttonText: {
16 | margin: 18,
17 | textAlign: 'center',
18 | color: Colors.snow,
19 | fontSize: Fonts.size.medium,
20 | fontFamily: Fonts.type.bold
21 | }
22 | })
23 |
--------------------------------------------------------------------------------
/Tests/Sagas/StartupSagaTest.js:
--------------------------------------------------------------------------------
1 | import test from 'ava'
2 | import { select, put } from 'redux-saga/effects'
3 | import { selectTemperature, startup } from '../../App/Sagas/StartupSagas'
4 | import TemperatureActions from '../../App/Redux/TemperatureRedux'
5 |
6 | const stepper = (fn) => (mock) => fn.next(mock).value
7 |
8 | test('watches for the right action', (t) => {
9 | const step = stepper(startup())
10 | TemperatureActions.temperatureRequest('San Francisco')
11 | t.deepEqual(step(), select(selectTemperature))
12 | t.deepEqual(step(), put(TemperatureActions.temperatureRequest('San Francisco')))
13 | })
14 |
--------------------------------------------------------------------------------
/App/Lib/axios/lib/core/enhanceError.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Update an Error with the specified config, error code, and response.
5 | *
6 | * @param {Error} error The error to update.
7 | * @param {Object} config The config.
8 | * @param {string} [code] The error code (for example, 'ECONNABORTED').
9 | @ @param {Object} [response] The response.
10 | * @returns {Error} The error.
11 | */
12 | module.exports = function enhanceError(error, config, code, response) {
13 | error.config = config;
14 | if (code) {
15 | error.code = code;
16 | }
17 | error.response = response;
18 | return error;
19 | };
20 |
--------------------------------------------------------------------------------
/App/Transforms/README.md:
--------------------------------------------------------------------------------
1 | # Transforms
2 |
3 | A common pattern when working with APIs is to change data to play nice between your app & the API.
4 |
5 | We've found this to be the case in every project we've worked on. So much so that we're recommending that you create a folder dedicated to these transformations.
6 |
7 | Transforms are not necessarily a bad thing (although an API might have you transforming more than you'd like).
8 |
9 | For example, you may:
10 |
11 | * turn appropriate strings to date objects
12 | * convert snake case to camel case
13 | * normalize or denormalize things
14 | * create lookup tables
15 |
--------------------------------------------------------------------------------
/App/Containers/Styles/AddContactModalStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import {StyleSheet, PixelRatio} from 'react-native'
4 | import {Colors, Metrics} from '../../Themes'
5 | import {create} from '../../Lib/PlatformStyleSheet'
6 |
7 | export default create({
8 | container: {
9 | flex: 1,
10 | justifyContent: 'flex-start',
11 | flexDirection: 'column'
12 | },
13 | body: {
14 | // flex: 1,
15 | height: 200,
16 | marginTop: 100,
17 | justifyContent: 'center',
18 | alignItems: 'center',
19 | paddingHorizontal: 33
20 | },
21 | button: {
22 | marginTop: 39,
23 | // flex: 0,
24 | }
25 | })
26 |
--------------------------------------------------------------------------------
/App/Containers/Styles/RootContainerStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import {StyleSheet} from 'react-native'
4 | import {Fonts, Metrics, Colors} from '../../Themes/'
5 |
6 | export default StyleSheet.create({
7 | applicationView: {
8 | flex: 1
9 | },
10 | container: {
11 | flex: 1,
12 | justifyContent: 'center',
13 | backgroundColor: Colors.background
14 | },
15 | welcome: {
16 | fontSize: 20,
17 | textAlign: 'center',
18 | fontFamily: Fonts.type.base,
19 | margin: Metrics.baseMargin
20 | },
21 | myImage: {
22 | width: 200,
23 | height: 200,
24 | alignSelf: 'center'
25 | }
26 | })
27 |
--------------------------------------------------------------------------------
/App/Components/Styles/RoundedButtonStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { StyleSheet } from 'react-native'
4 | import { Fonts, Colors, Metrics } from '../../Themes/'
5 |
6 | export default StyleSheet.create({
7 | button: {
8 | height: 45,
9 | borderRadius: 5,
10 | marginHorizontal: Metrics.section,
11 | marginVertical: Metrics.baseMargin,
12 | backgroundColor: Colors.fire,
13 | justifyContent: 'center'
14 | },
15 | buttonText: {
16 | color: Colors.snow,
17 | textAlign: 'center',
18 | fontWeight: 'bold',
19 | fontSize: Fonts.size.medium,
20 | marginVertical: Metrics.baseMargin
21 | }
22 | })
23 |
--------------------------------------------------------------------------------
/fastlane/Appfile:
--------------------------------------------------------------------------------
1 | # iOS
2 | # app_identifier "com.infinitered.ignite" # The bundle identifier of your app
3 | # apple_id "thisIsMe@gmail.com" # Your Apple email address
4 | # team_id "3FTD6ME549" # Developer Portal Team ID
5 |
6 | # Android
7 | # json_key_file "./google-play-api-secret.json" # Path to the json secret file - Follow https://github.com/fastlane/supply#setup to get one
8 | # package_name "com.infinitered.myapp" # You Android app package
9 |
10 | # you can even provide different app identifiers, Apple IDs and team names per lane:
11 | # More information: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Appfile.md
12 |
--------------------------------------------------------------------------------
/App/Lib/axios/http_proxy.txt:
--------------------------------------------------------------------------------
1 | process.env.http_proxy
2 |
3 | var http = require("http");
4 |
5 | var options = {
6 | host: "proxy",
7 | port: 8080,
8 | path: "http://www.google.com",
9 | headers: {
10 | Host: "www.google.com"
11 | }
12 | };
13 | http.get(options, function(res) {
14 | console.log(res);
15 | res.pipe(process.stdout);
16 | });
17 |
18 |
19 | process.env.https_proxy
20 |
21 | var http = require('http');
22 |
23 | http.get ({
24 | host: '127.0.0.1',
25 | port: 8888,
26 | path: 'https://www.google.com/accounts/OAuthGetRequestToken'
27 | }, function (response) {
28 | console.log (response);
29 | });
30 |
--------------------------------------------------------------------------------
/App/Lib/axios/lib/helpers/isAbsoluteURL.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Determines whether the specified URL is absolute
5 | *
6 | * @param {string} url The URL to test
7 | * @returns {boolean} True if the specified URL is absolute, otherwise false
8 | */
9 | module.exports = function isAbsoluteURL(url) {
10 | // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL).
11 | // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
12 | // by any combination of letters, digits, plus, period, or hyphen.
13 | return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
14 | };
15 |
--------------------------------------------------------------------------------
/App/Lib/axios/lib/core/createError.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var enhanceError = require('./enhanceError');
4 |
5 | /**
6 | * Create an Error with the specified message, config, error code, and response.
7 | *
8 | * @param {string} message The error message.
9 | * @param {Object} config The config.
10 | * @param {string} [code] The error code (for example, 'ECONNABORTED').
11 | @ @param {Object} [response] The response.
12 | * @returns {Error} The created error.
13 | */
14 | module.exports = function createError(message, config, code, response) {
15 | var error = new Error(message);
16 | return enhanceError(error, config, code, response);
17 | };
18 |
--------------------------------------------------------------------------------
/App/Config/ReduxPersist.js:
--------------------------------------------------------------------------------
1 | import immutablePersistenceTransform from '../Services/ImmutablePersistenceTransform'
2 | import { AsyncStorage } from 'react-native'
3 |
4 | const REDUX_PERSIST = {
5 | active: true,
6 | reducerVersion: '2',
7 | storeConfig: {
8 | storage: AsyncStorage,
9 | blacklist: ['login'], // reducer keys that you do NOT want stored to persistence here
10 | whitelist: [], // Optionally, just specify the keys you DO want stored to
11 | // persistence. An empty array means 'don't store any reducers' -> infinitered/ignite#409
12 | transforms: [immutablePersistenceTransform]
13 | }
14 | }
15 |
16 | export default REDUX_PERSIST
17 |
--------------------------------------------------------------------------------
/App/Lib/axios/lib/core/transformData.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('./../utils');
4 |
5 | /**
6 | * Transform the data for a request or a response
7 | *
8 | * @param {Object|String} data The data to be transformed
9 | * @param {Array} headers The headers for the request or response
10 | * @param {Array|Function} fns A single function or Array of functions
11 | * @returns {*} The resulting transformed data
12 | */
13 | module.exports = function transformData(data, headers, fns) {
14 | /*eslint no-param-reassign:0*/
15 | utils.forEach(fns, function transform(fn) {
16 | data = fn(data, headers);
17 | });
18 |
19 | return data;
20 | };
21 |
--------------------------------------------------------------------------------
/App/Components/TabIcon.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | PropTypes,
3 | } from 'react';
4 | import {
5 | Text,
6 | Image,
7 | View
8 | } from 'react-native';
9 |
10 | const propTypes = {
11 | selected: PropTypes.bool,
12 | title: PropTypes.string,
13 | };
14 |
15 | const TabIcon = (props) => (
16 |
17 | {props.image ? : null}
18 | {props.title ?
21 | {props.title}
22 | : null
23 | }
24 |
25 | );
26 |
27 | TabIcon.propTypes = propTypes;
28 |
29 | export default TabIcon;
30 |
--------------------------------------------------------------------------------
/Tests/Sagas/LoginSagaTest.js:
--------------------------------------------------------------------------------
1 | import test from 'ava'
2 | import { put } from 'redux-saga/effects'
3 | import { login } from '../../App/Sagas/LoginSagas'
4 | import LoginActions from '../../App/Redux/LoginRedux'
5 |
6 | const stepper = (fn) => (mock) => fn.next(mock).value
7 |
8 | test('success', (t) => {
9 | const mock = { username: 'a', password: 'b' }
10 | const step = stepper(login(mock))
11 |
12 | t.deepEqual(step(), put(LoginActions.loginSuccess(mock.username)))
13 | })
14 |
15 | test('failure', (t) => {
16 | const mock = { username: '', password: '' }
17 | const step = stepper(login(mock))
18 |
19 | t.deepEqual(step(), put(LoginActions.loginFailure('WRONG')))
20 | })
21 |
--------------------------------------------------------------------------------
/App/Navigation/Styles/NavigationContainerStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import {StyleSheet, Platform} from 'react-native'
3 | import {Colors} from '../../Themes/'
4 |
5 | export default {
6 | container: {
7 | flex: 1
8 | },
9 | navBar: {
10 | backgroundColor: Colors.background
11 | },
12 | title: {
13 | color: Colors.snow
14 | },
15 | leftButton: {
16 | tintColor: Colors.snow
17 | },
18 | rightButton: {
19 | color: Colors.snow
20 | },
21 | tabBarStyle: {
22 | borderTopWidth: StyleSheet.hairlineWidth,
23 | borderColor: '#b7b7b7',
24 | backgroundColor: Colors.white1,
25 | justifyContent: 'center',
26 | opacity: 1,
27 | height: 50,
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/App/Redux/ContactsScreenRedux.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import {createReducer, createActions} from 'reduxsauce'
4 | import Immutable from 'seamless-immutable'
5 |
6 | /* ------------- Types and Action Creators ------------- */
7 |
8 | const {Types, Creators} = createActions({
9 | nop: null
10 | })
11 |
12 | export const ContactsTypes = Types
13 | export default Creators
14 |
15 | /* ------------- Initial State ------------- */
16 | export const INITIAL_STATE = Immutable({})
17 |
18 | /* ------------- Reducers ------------- */
19 |
20 | /* ------------- Hookup Reducers To Types ------------- */
21 | export const reducer = createReducer(INITIAL_STATE, {})
22 |
23 | /* ------------- Selectors ------------- */
24 |
--------------------------------------------------------------------------------
/App/Lib/axios/lib/helpers/spread.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Syntactic sugar for invoking a function and expanding an array for arguments.
5 | *
6 | * Common use case would be to use `Function.prototype.apply`.
7 | *
8 | * ```js
9 | * function f(x, y, z) {}
10 | * var args = [1, 2, 3];
11 | * f.apply(null, args);
12 | * ```
13 | *
14 | * With `spread` this example can be re-written.
15 | *
16 | * ```js
17 | * spread(function(x, y, z) {})([1, 2, 3]);
18 | * ```
19 | *
20 | * @param {Function} callback
21 | * @returns {Function}
22 | */
23 | module.exports = function spread(callback) {
24 | return function wrap(arr) {
25 | return callback.apply(null, arr);
26 | };
27 | };
28 |
--------------------------------------------------------------------------------
/App/Components/Styles/AlertMessageStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { StyleSheet } from 'react-native'
4 | import { Colors, Metrics, Fonts } from '../../Themes/'
5 |
6 | export default StyleSheet.create({
7 | container: {
8 | justifyContent: 'center',
9 | marginVertical: Metrics.section
10 | },
11 | contentContainer: {
12 | alignSelf: 'center',
13 | alignItems: 'center'
14 | },
15 | message: {
16 | marginTop: Metrics.baseMargin,
17 | marginHorizontal: Metrics.baseMargin,
18 | textAlign: 'center',
19 | fontFamily: Fonts.type.base,
20 | fontSize: Fonts.size.regular,
21 | fontWeight: 'bold',
22 | color: Colors.steel
23 | },
24 | icon: {
25 | color: Colors.steel
26 | }
27 | })
28 |
--------------------------------------------------------------------------------
/App/Sagas/TemperatureSagas.js:
--------------------------------------------------------------------------------
1 | import { call, put } from 'redux-saga/effects'
2 | import { path } from 'ramda'
3 | import TemperatureActions from '../Redux/TemperatureRedux'
4 | import convertFromKelvin from '../Transforms/ConvertFromKelvin'
5 |
6 | export function * getTemperature (api, action) {
7 | const { city } = action
8 | // make the call to the api
9 | const response = yield call(api.getCity, city)
10 |
11 | // success?
12 | if (response.ok) {
13 | const kelvin = path(['data', 'main', 'temp_max'], response)
14 | const temperature = convertFromKelvin(kelvin)
15 | yield put(TemperatureActions.temperatureSuccess(temperature, 'bonus'))
16 | } else {
17 | yield put(TemperatureActions.temperatureFailure())
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/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.2'
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/app.xcodeproj/xcuserdata/lwz.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | app.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 00E356ED1AD99517003FC87E
16 |
17 | primary
18 |
19 |
20 | 13B07F861A680F5B00A75B9A
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/App/Components/Styles/CustomNavBarStyle.js:
--------------------------------------------------------------------------------
1 | import { Colors, Metrics } from '../../Themes/'
2 |
3 | export default {
4 | container: {
5 | position: 'absolute',
6 | top: 0,
7 | left: 0,
8 | right: 0,
9 | height: Metrics.navBarHeight,
10 | paddingHorizontal: Metrics.baseMargin,
11 | backgroundColor: Colors.background,
12 | flexDirection: 'row',
13 | alignItems: 'center',
14 | justifyContent: 'space-between'
15 | },
16 | leftButton: {
17 | paddingTop: Metrics.baseMargin
18 | },
19 | logo: {
20 | height: Metrics.navBarHeight - Metrics.doubleBaseMargin,
21 | width: Metrics.navBarHeight - Metrics.doubleBaseMargin,
22 | resizeMode: 'contain'
23 | },
24 | rightButton: {
25 | paddingTop: Metrics.baseMargin
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ios/app.xcodeproj/project.xcworkspace/xcuserdata/lwz.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildLocationStyle
6 | CustomLocation
7 | CustomBuildIntermediatesPath
8 | Build/Intermediates
9 | CustomBuildLocationType
10 | RelativeToWorkspace
11 | CustomBuildProductsPath
12 | Build/Products
13 | DerivedDataLocationStyle
14 | Default
15 | IssueFilterStyle
16 | ShowActiveSchemeOnly
17 | LiveSourceIssuesEnabled
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Tests/Reducers/LoginReducerTest.js:
--------------------------------------------------------------------------------
1 | import test from 'ava'
2 | import Actions, { reducer, INITIAL_STATE } from '../../App/Redux/LoginRedux'
3 |
4 | test('attempt', (t) => {
5 | const state = reducer(INITIAL_STATE, Actions.loginRequest('u', 'p'))
6 |
7 | t.true(state.fetching)
8 | })
9 |
10 | test('success', (t) => {
11 | const state = reducer(INITIAL_STATE, Actions.loginSuccess('hi'))
12 |
13 | t.is(state.username, 'hi')
14 | })
15 |
16 | test('failure', (t) => {
17 | const state = reducer(INITIAL_STATE, Actions.loginFailure(69))
18 |
19 | t.false(state.fetching)
20 | t.is(state.error, 69)
21 | })
22 |
23 | test('logout', (t) => {
24 | const loginState = reducer(INITIAL_STATE, Actions.loginSuccess('hi'))
25 | const state = reducer(loginState, Actions.logout())
26 |
27 | t.falsy(state.username)
28 | })
29 |
--------------------------------------------------------------------------------
/App/Lib/axios/lib/core/settle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var createError = require('./createError');
4 |
5 | /**
6 | * Resolve or reject a Promise based on response status.
7 | *
8 | * @param {Function} resolve A function that resolves the promise.
9 | * @param {Function} reject A function that rejects the promise.
10 | * @param {object} response The response.
11 | */
12 | module.exports = function settle(resolve, reject, response) {
13 | var validateStatus = response.config.validateStatus;
14 | // Note: status is not exposed by XDomainRequest
15 | if (!response.status || !validateStatus || validateStatus(response.status)) {
16 | resolve(response);
17 | } else {
18 | reject(createError(
19 | 'Request failed with status code ' + response.status,
20 | response.config,
21 | null,
22 | response
23 | ));
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/App/Lib/axios/lib/helpers/deprecatedMethod.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*eslint no-console:0*/
4 |
5 | /**
6 | * Supply a warning to the developer that a method they are using
7 | * has been deprecated.
8 | *
9 | * @param {string} method The name of the deprecated method
10 | * @param {string} [instead] The alternate method to use if applicable
11 | * @param {string} [docs] The documentation URL to get further details
12 | */
13 | module.exports = function deprecatedMethod(method, instead, docs) {
14 | try {
15 | console.warn(
16 | 'DEPRECATED method `' + method + '`.' +
17 | (instead ? ' Use `' + instead + '` instead.' : '') +
18 | ' This method will be removed in a future release.');
19 |
20 | if (docs) {
21 | console.warn('For more information about usage see ' + docs);
22 | }
23 | } catch (e) { /* Ignore */ }
24 | };
25 |
--------------------------------------------------------------------------------
/Tests/Reducers/TemperatureReducerTest.js:
--------------------------------------------------------------------------------
1 | import test from 'ava'
2 | import Actions, { reducer, INITIAL_STATE } from '../../App/Redux/TemperatureRedux'
3 |
4 | test('request', (t) => {
5 | const cityName = 'someCity'
6 | const state = reducer(INITIAL_STATE, Actions.temperatureRequest(cityName))
7 |
8 | t.true(state.fetching)
9 | t.is(state.city, cityName)
10 | t.is(null, state.temperature)
11 | })
12 |
13 | test('success', (t) => {
14 | const cityTemp = 69
15 | const state = reducer(INITIAL_STATE, Actions.temperatureSuccess(cityTemp))
16 |
17 | t.false(state.fetching)
18 | t.is(state.temperature, cityTemp)
19 | t.is(null, state.error)
20 | })
21 |
22 | test('failure', (t) => {
23 | const state = reducer(INITIAL_STATE, Actions.temperatureFailure())
24 |
25 | t.false(state.fetching)
26 | t.true(state.error)
27 | t.is(null, state.temperature)
28 | })
29 |
--------------------------------------------------------------------------------
/App/Components/CustomNavBar.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { View, Image, Animated, TouchableOpacity } from 'react-native'
3 | import { Images, Colors } from '../Themes'
4 | import Styles from './Styles/CustomNavBarStyle'
5 | import Icon from 'react-native-vector-icons/Ionicons'
6 | import { Actions as NavigationActions } from 'react-native-router-flux'
7 |
8 | export default class CustomNavBar extends React.Component {
9 | render () {
10 | return (
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | )
19 | }
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/ios/appTests/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 |
--------------------------------------------------------------------------------
/App/Containers/Styles/ListviewExampleStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { StyleSheet } from 'react-native'
4 | import { ApplicationStyles, Metrics, Colors } from '../../Themes/'
5 |
6 | export default StyleSheet.create({
7 | ...ApplicationStyles.screen,
8 | container: {
9 | flex: 1,
10 | marginTop: Metrics.navBarHeight,
11 | backgroundColor: Colors.background
12 | },
13 | row: {
14 | flex: 1,
15 | backgroundColor: Colors.fire,
16 | marginVertical: Metrics.smallMargin,
17 | justifyContent: 'center'
18 | },
19 | boldLabel: {
20 | fontWeight: 'bold',
21 | alignSelf: 'center',
22 | color: Colors.snow,
23 | textAlign: 'center',
24 | marginBottom: Metrics.smallMargin
25 | },
26 | label: {
27 | textAlign: 'center',
28 | color: Colors.snow
29 | },
30 | listContent: {
31 | marginTop: Metrics.baseMargin
32 | }
33 | })
34 |
--------------------------------------------------------------------------------
/App/Fixtures/boise.json:
--------------------------------------------------------------------------------
1 | {
2 | "coord":{
3 | "lon":-116.2,
4 | "lat":43.61
5 | },
6 | "weather":[
7 | {
8 | "id":803,
9 | "main":"Clouds",
10 | "description":"broken clouds",
11 | "icon":"04n"
12 | }
13 | ],
14 | "base":"stations",
15 | "main":{
16 | "temp":294.76,
17 | "pressure":1015,
18 | "humidity":20,
19 | "temp_min":294.15,
20 | "temp_max":296.15
21 | },
22 | "visibility":16093,
23 | "wind":{
24 | "speed":3.6,
25 | "deg":130
26 | },
27 | "clouds":{
28 | "all":75
29 | },
30 | "dt":1474172351,
31 | "sys":{
32 | "type":1,
33 | "id":911,
34 | "message":0.0333,
35 | "country":"US",
36 | "sunrise":1474205304,
37 | "sunset":1474249684
38 | },
39 | "id":5586437,
40 | "name":"Boise",
41 | "cod":200
42 | }
--------------------------------------------------------------------------------
/App/Fixtures/toronto.json:
--------------------------------------------------------------------------------
1 | {
2 | "coord":{
3 | "lon":-79.38,
4 | "lat":43.65
5 | },
6 | "weather":[
7 | {
8 | "id":701,
9 | "main":"Mist",
10 | "description":"mist",
11 | "icon":"50n"
12 | }
13 | ],
14 | "base":"stations",
15 | "main":{
16 | "temp":292.05,
17 | "pressure":1012,
18 | "humidity":94,
19 | "temp_min":290.37,
20 | "temp_max":293.71
21 | },
22 | "visibility":14484,
23 | "wind":{
24 | "speed":3.1,
25 | "deg":230
26 | },
27 | "clouds":{
28 | "all":1
29 | },
30 | "dt":1474172343,
31 | "sys":{
32 | "type":1,
33 | "id":3721,
34 | "message":0.037,
35 | "country":"CA",
36 | "sunrise":1474196460,
37 | "sunset":1474240859
38 | },
39 | "id":6167863,
40 | "name":"Downtown Toronto",
41 | "cod":200
42 | }
--------------------------------------------------------------------------------
/App/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 |
--------------------------------------------------------------------------------
/App/Components/DrawerButton.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import React, { Component } from 'react'
4 | import { Text, TouchableOpacity } from 'react-native'
5 | import styles from './Styles/DrawerButtonStyles'
6 | import ExamplesRegistry from '../Services/ExamplesRegistry'
7 |
8 | // Example
9 | ExamplesRegistry.add('Drawer Button', () =>
10 | window.alert('Your drawers are showing')}
13 | />
14 | )
15 |
16 | type DrawerButtonProps = {
17 | text: string,
18 | onPress: () => void
19 | }
20 |
21 | class DrawerButton extends Component {
22 | props: DrawerButtonProps
23 |
24 | render () {
25 | return (
26 |
27 | {this.props.text}
28 |
29 | )
30 | }
31 | }
32 |
33 | export default DrawerButton
34 |
--------------------------------------------------------------------------------
/App/Themes/Metrics.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import {Dimensions, Platform} from 'react-native'
4 |
5 | const {width, height} = Dimensions.get('window')
6 |
7 | // Used via Metrics.baseMargin
8 | const metrics = {
9 | marginHorizontal: 10,
10 | marginVertical: 10,
11 | section: 25,
12 | baseMargin: 10,
13 | doubleBaseMargin: 20,
14 | smallMargin: 5,
15 | horizontalLineHeight: 1,
16 | screenWidth: width < height ? width : height,
17 | screenHeight: width < height ? height : width,
18 | navBarHeight: (Platform.OS === 'ios') ? 64 : 54,
19 | statusBarHeight: 20,
20 | buttonRadius: 4,
21 | icons: {
22 | tiny0: 13,
23 | tiny: 15,
24 | tiny2: 17,
25 | small: 20,
26 | medium: 30,
27 | large: 45,
28 | xl: 60
29 | },
30 | images: {
31 | small: 20,
32 | medium: 40,
33 | large: 60,
34 | logo: 300
35 | }
36 | }
37 |
38 | export default metrics
39 |
--------------------------------------------------------------------------------
/android/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/App/Components/FullButton.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import React from 'react'
4 | import { TouchableOpacity, Text } from 'react-native'
5 | import styles from './Styles/FullButtonStyle'
6 | import ExamplesRegistry from '../Services/ExamplesRegistry'
7 |
8 | // Example
9 | ExamplesRegistry.add('Full Button', () =>
10 | window.alert('Full Button Pressed!')}
13 | />
14 | )
15 |
16 | type FullButtonProps = {
17 | text: string,
18 | onPress: () => void,
19 | styles?: Object
20 | }
21 |
22 | export default class FullButton extends React.Component {
23 | props: FullButtonProps
24 |
25 | render () {
26 | return (
27 |
28 | {this.props.text && this.props.text.toUpperCase()}
29 |
30 | )
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/App/Lib/axios/lib/helpers/parseHeaders.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('./../utils');
4 |
5 | /**
6 | * Parse headers into an object
7 | *
8 | * ```
9 | * Date: Wed, 27 Aug 2014 08:58:49 GMT
10 | * Content-Type: application/json
11 | * Connection: keep-alive
12 | * Transfer-Encoding: chunked
13 | * ```
14 | *
15 | * @param {String} headers Headers needing to be parsed
16 | * @returns {Object} Headers parsed into an object
17 | */
18 | module.exports = function parseHeaders(headers) {
19 | var parsed = {};
20 | var key;
21 | var val;
22 | var i;
23 |
24 | if (!headers) { return parsed; }
25 |
26 | utils.forEach(headers.split('\n'), function parser(line) {
27 | i = line.indexOf(':');
28 | key = utils.trim(line.substr(0, i)).toLowerCase();
29 | val = utils.trim(line.substr(i + 1));
30 |
31 | if (key) {
32 | parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
33 | }
34 | });
35 |
36 | return parsed;
37 | };
38 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/App/Services/ExamplesRegistry.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import React from 'react'
4 | import { Text, View } from 'react-native'
5 | import R from 'ramda'
6 | import { ApplicationStyles } from '../Themes'
7 | import DebugSettings from '../Config/DebugSettings'
8 | let globalExamplesRegistry = []
9 |
10 | export const addExample = (title: string, usage: () => React$Element<*>) => { if (DebugSettings.includeExamples) globalExamplesRegistry.push({title, usage}) }
11 |
12 | const renderExample = (example: Object) => {
13 | return (
14 |
15 |
16 | {example.title}
17 |
18 | {example.usage.call()}
19 |
20 | )
21 | }
22 |
23 | export const renderExamples = () => R.map(renderExample, globalExamplesRegistry)
24 |
25 | // Default for readability
26 | export default {
27 | render: renderExamples,
28 | add: addExample
29 | }
30 |
--------------------------------------------------------------------------------
/App/Containers/Styles/UsageExamplesScreenStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { StyleSheet } from 'react-native'
4 | import { Colors, Fonts, Metrics, ApplicationStyles } from '../../Themes/'
5 |
6 | export default StyleSheet.create({
7 | ...ApplicationStyles.screen,
8 | loginBox: {
9 | padding: Metrics.doubleBaseMargin
10 | },
11 | loginButton: {
12 | borderWidth: 1,
13 | borderColor: Colors.charcoal,
14 | backgroundColor: Colors.panther,
15 | padding: 6
16 | },
17 | loginText: {
18 | textAlign: 'center',
19 | color: Colors.silver
20 | },
21 | componentLabelContainer: {
22 | ...ApplicationStyles.darkLabelContainer
23 | },
24 | componentLabel: {
25 | ...ApplicationStyles.darkLabel
26 | },
27 | temperature: {
28 | ...Fonts.style.h4,
29 | color: Colors.snow
30 | },
31 | locale: {
32 | ...Fonts.style.h4,
33 | color: Colors.snow
34 | },
35 | groupContainer: {
36 | ...ApplicationStyles.groupContainer
37 | }
38 | })
39 |
--------------------------------------------------------------------------------
/App/Redux/CommonRedux.js:
--------------------------------------------------------------------------------
1 | import {createReducer, createActions} from 'reduxsauce'
2 | import Immutable from 'seamless-immutable'
3 |
4 | /* ------------- Types and Action Creators ------------- */
5 |
6 | const {Types, Creators} = createActions({
7 | fetching: [],
8 | fetched: [],
9 | })
10 |
11 | export const CommonTypes = Types
12 | export default Creators
13 |
14 | /* ------------- Initial State ------------- */
15 |
16 | export const INITIAL_STATE = Immutable({
17 | fetching: false,
18 | })
19 |
20 | /* ------------- Reducers ------------- */
21 |
22 | export const fetching = (state) => {
23 | return state.merge({fetching: true})
24 | }
25 |
26 | export const fetched = (state) => {
27 | return state.merge({fetching: false})
28 | }
29 |
30 | /* ------------- Hookup Reducers To Types ------------- */
31 |
32 | export const reducer = createReducer(INITIAL_STATE, {
33 | [Types.FETCHING]: fetching,
34 | [Types.FETCHED]: fetched,
35 | })
36 |
37 | /* ------------- Selectors ------------- */
38 |
--------------------------------------------------------------------------------
/Tests/Components/DrawerButtonTest.js:
--------------------------------------------------------------------------------
1 | // https://github.com/airbnb/enzyme/blob/master/docs/api/shallow.md
2 | import test from 'ava'
3 | import React from 'react'
4 | import DrawerButton from '../../App/Components/DrawerButton'
5 | import { shallow } from 'enzyme'
6 |
7 | const wrapper = shallow( {}} text='hi' />)
8 |
9 | test('component exists', (t) => {
10 | t.is(wrapper.length, 1) // exists
11 | })
12 |
13 | test('component structure', (t) => {
14 | t.is(wrapper.name(), 'TouchableOpacity') // the right root component
15 | t.is(wrapper.children().length, 1) // has 1 child
16 | t.is(wrapper.children().first().name(), 'Text') // that child is Text
17 | })
18 |
19 | test('onPress', (t) => {
20 | let i = 0
21 | const onPress = () => i++
22 | const wrapperPress = shallow()
23 |
24 | t.is(wrapperPress.prop('onPress'), onPress) // uses the right handler
25 | t.is(i, 0)
26 | wrapperPress.simulate('press')
27 | t.is(i, 1)
28 | })
29 |
--------------------------------------------------------------------------------
/App/I18n/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "signIn": "Se connecter",
3 | "logOut": "Se déconnecter",
4 | "loginLogoutExampleTitle": "Connexion / Déconnexion Redux + Sagas Exemple",
5 | "progressiveImageComponent": "Composant Image Progressive",
6 | "api": "Mon Dieu! Une API pour vous!",
7 | "locale": "I18n Paramètres régionaux",
8 | "rnVectorIcons": "RN icônes vectorielles",
9 | "loginWithFacebook": "Se connecter avec Facebook",
10 | "rnAnimatable": "RN Animatable",
11 | "igniteGenerated": "Ignite Générer des Écrans",
12 | "forgotPassword": "Mot de passe oublié",
13 | "username": "Nom d'utilisateur",
14 | "password": "Mot de passe",
15 | "cancel": "Annuler",
16 | "welcome": "Bienvenue",
17 | "login": "S'identifier",
18 | "tempIndicator": "C",
19 | "componentExamples": "Exemples de Composants",
20 | "usageExamples": "Exemples d'utilisation",
21 | "apiTesting": "API Testing",
22 | "themeSettings": "Réglage des thèmes",
23 | "deviceDetails": "Détails du périphérique",
24 | "noItems": "Aucun"
25 | }
26 |
--------------------------------------------------------------------------------
/App/Containers/Styles/GroupListScreenStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import {StyleSheet} from 'react-native'
4 | import {Colors, Metrics, Fonts} from '../../Themes'
5 | import {create} from '../../Lib/PlatformStyleSheet'
6 |
7 | export default create({
8 | // ListView
9 | listView: {
10 | flex: 1,
11 | },
12 | row: {
13 | marginLeft: 15,
14 | height: 70,
15 | justifyContent: 'center',
16 | alignItems: 'center',
17 | flexDirection: 'row'
18 | },
19 | separator: {
20 | height: StyleSheet.hairlineWidth,
21 | marginLeft: 15,
22 | backgroundColor: '#CCCCCC',
23 | },
24 | rowLogo: {
25 | width: 50,
26 | height: 50,
27 | borderRadius: 25
28 | },
29 | rowName: {
30 | flex: 1,
31 | justifyContent: 'center',
32 | marginLeft: 10
33 | },
34 | groupName: {
35 | ...Fonts.style.rowText,
36 | color: Colors.almostBlack,
37 | },
38 | groupIntro: {
39 | ...Fonts.style.rowText,
40 | marginTop: 10,
41 | color: Colors.steelGrey,
42 | }
43 |
44 | })
45 |
--------------------------------------------------------------------------------
/App/Containers/README.md:
--------------------------------------------------------------------------------
1 | ### Containers Folder
2 | A container is what they call a "Smart Component" in Redux. It is a component
3 | which knows about Redux. They are usually used as "Screens".
4 |
5 | Also located in here are 2 special containers: `App.js` and `RootContainer.js`.
6 |
7 | `App.js` is first component loaded after `index.ios.js` or `index.android.js`. The purpose of this file is to setup Redux or any other non-visual "global" modules. Having Redux setup here helps with the hot-reloading process in React Native during development as it won't try to reload your sagas and reducers should your colors change (for example).
8 |
9 | `RootContainer.js` is the first visual component in the app. It is the ancestor of all other screens and components.
10 |
11 | You'll probably find you'll have great mileage in Ignite apps without even touching these 2 files. They, of course, belong to you, so when you're ready to add something non-visual like Firebase or something visual like an overlay, you have spots to place these additions.
12 |
--------------------------------------------------------------------------------
/App/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 | '[ {}} text='hi' />)
9 |
10 | test('component exists', (t) => {
11 | t.is(wrapper.length, 1) // exists
12 | })
13 |
14 | test('component structure', (t) => {
15 | t.is(wrapper.name(), 'TouchableOpacity') // the right root component
16 | t.is(wrapper.children().length, 1) // has 1 child
17 | t.is(wrapper.children().first().name(), 'Text') // that child is Text
18 | })
19 |
20 | test('onPress', (t) => {
21 | let i = 0 // i guess i could have used sinon here too... less is more i guess
22 | const onPress = () => i++
23 | const wrapperPress = shallow()
24 |
25 | t.is(wrapperPress.prop('onPress'), onPress) // uses the right handler
26 | t.is(i, 0)
27 | wrapperPress.simulate('press')
28 | t.is(i, 1)
29 | })
30 |
--------------------------------------------------------------------------------
/App/Components/RoundedButton.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import React from 'react'
4 | import { TouchableOpacity, Text } from 'react-native'
5 | import styles from './Styles/RoundedButtonStyle'
6 | import ExamplesRegistry from '../Services/ExamplesRegistry'
7 |
8 | // Example
9 | ExamplesRegistry.add('Rounded Button', () =>
10 | window.alert('Rounded Button Pressed!')}
13 | />
14 | )
15 |
16 | type RoundedButtonProps = {
17 | onPress: () => void,
18 | text?: string,
19 | children?: string,
20 | navigator?: Object
21 | }
22 |
23 | export default class RoundedButton extends React.Component {
24 | props: RoundedButtonProps
25 |
26 | getText () {
27 | const buttonText = this.props.text || this.props.children || ''
28 | return buttonText.toUpperCase()
29 | }
30 |
31 | render () {
32 | return (
33 |
34 | {this.getText()}
35 |
36 | )
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/App/Redux/ContactInfoScreenRedux.js:
--------------------------------------------------------------------------------
1 | import {createReducer, createActions} from 'reduxsauce'
2 | import Immutable from 'seamless-immutable'
3 |
4 | /* ------------- Types and Action Creators ------------- */
5 |
6 | const {Types, Creators} = createActions({
7 | contactDeleted: [],
8 | contactShowed: []
9 | })
10 |
11 | export const ContactInfoScreenTypes = Types
12 | export default Creators
13 |
14 | /* ------------- Initial State ------------- */
15 |
16 | export const INITIAL_STATE = Immutable({
17 | show: true,
18 | })
19 |
20 | /* ------------- Reducers ------------- */
21 |
22 | export const contactDeleted = (state, {}) => {
23 | return state.merge({show: false})
24 | }
25 |
26 | export const contactShowed = (state, {}) => {
27 | return state.merge({show: true})
28 | }
29 | /* ------------- Hookup Reducers To Types ------------- */
30 |
31 | export const reducer = createReducer(INITIAL_STATE, {
32 | [Types.CONTACT_DELETED]: contactDeleted,
33 | [Types.CONTACT_SHOWED]: contactShowed,
34 | })
35 |
36 | /* ------------- Selectors ------------- */
37 |
38 | // Is the current user logged in?
39 |
--------------------------------------------------------------------------------
/App/Containers/Styles/GroupMembersScreenStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import {StyleSheet} from 'react-native'
4 | import {Colors, Metrics, Fonts} from '../../Themes'
5 | import {create} from '../../Lib/PlatformStyleSheet'
6 |
7 | export default create({
8 | // ListView
9 | listView: {
10 | // flex: 1,
11 | backgroundColor: Colors.paleGrey
12 | },
13 | row: {
14 | paddingLeft: 15,
15 | height: 50,
16 | justifyContent: 'center',
17 | alignItems: 'center',
18 | flexDirection: 'row',
19 | backgroundColor: Colors.snow
20 | },
21 | separator: {
22 | height: StyleSheet.hairlineWidth,
23 | marginLeft: 15,
24 | backgroundColor: '#CCCCCC',
25 | },
26 | rowLogo: {
27 | width: 30,
28 | height: 30,
29 | borderRadius: 15
30 | },
31 | rowName: {
32 | flex: 1,
33 | justifyContent: 'center',
34 | marginLeft: 10
35 | },
36 | groupName: {
37 | ...Fonts.style.rowText,
38 | color: Colors.almostBlack,
39 | },
40 | groupIntro: {
41 | ...Fonts.style.rowText,
42 | marginTop: 10,
43 | color: Colors.steelGrey,
44 | }
45 |
46 | })
47 |
--------------------------------------------------------------------------------
/App/Lib/axios/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014 Matt Zabriskie
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/App/Navigation/NavItems.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import React from 'react'
4 | import { TouchableOpacity } from 'react-native'
5 | import styles from './Styles/NavItemsStyle'
6 | import { Actions as NavigationActions } from 'react-native-router-flux'
7 | import Icon from 'react-native-vector-icons/FontAwesome'
8 | import { Colors, Metrics } from '../Themes'
9 |
10 | const openDrawer = () => {
11 | NavigationActions.refresh({
12 | key: 'drawer',
13 | open: true
14 | })
15 | }
16 |
17 | export default {
18 | backButton () {
19 | return (
20 |
21 |
26 |
27 | )
28 | },
29 |
30 | hamburgerButton () {
31 | return (
32 |
33 |
38 |
39 | )
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/App/Lib/axios/lib/helpers/btoa.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // btoa polyfill for IE<10 courtesy https://github.com/davidchambers/Base64.js
4 |
5 | var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
6 |
7 | function E() {
8 | this.message = 'String contains an invalid character';
9 | }
10 | E.prototype = new Error;
11 | E.prototype.code = 5;
12 | E.prototype.name = 'InvalidCharacterError';
13 |
14 | function btoa(input) {
15 | var str = String(input);
16 | var output = '';
17 | for (
18 | // initialize result and counter
19 | var block, charCode, idx = 0, map = chars;
20 | // if the next str index does not exist:
21 | // change the mapping table to "="
22 | // check if d has no fractional digits
23 | str.charAt(idx | 0) || (map = '=', idx % 1);
24 | // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8
25 | output += map.charAt(63 & block >> 8 - idx % 1 * 8)
26 | ) {
27 | charCode = str.charCodeAt(idx += 3 / 4);
28 | if (charCode > 0xFF) {
29 | throw new E();
30 | }
31 | block = block << 8 | charCode;
32 | }
33 | return output;
34 | }
35 |
36 | module.exports = btoa;
37 |
--------------------------------------------------------------------------------
/App/Components/Styles/ModalHeaderStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { StyleSheet, PixelRatio } from 'react-native'
4 | import { Colors, Metrics } from '../../Themes'
5 | import { create } from '../../Lib/PlatformStyleSheet'
6 |
7 | export default create({
8 | container: {
9 | // flex: 1,
10 | flexDirection: 'row',
11 | height: 42,
12 | backgroundColor: Colors.bgGrey,
13 | justifyContent: 'center',
14 | borderBottomWidth: StyleSheet.hairlineWidth,
15 | borderBottomColor: Colors.paleGrey,
16 | },
17 | left: {
18 | flex: 1,
19 | justifyContent: 'center',
20 | alignItems: 'flex-start',
21 | paddingLeft: 15,
22 | },
23 | leftText: {
24 | fontSize: 13,
25 | color: Colors.modelHeaderText
26 | },
27 | middle: {
28 | flex: 1,
29 | justifyContent: 'center',
30 | alignItems: 'center',
31 | },
32 | middleText: {
33 | fontSize: 17,
34 | marginBottom: 3
35 | },
36 | right: {
37 | flex: 1,
38 | justifyContent: 'center',
39 | alignItems: 'flex-end',
40 | paddingRight: 15,
41 | },
42 | rightText: {
43 | fontSize: 13,
44 | color: Colors.modelHeaderText
45 | },
46 | })
47 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | # 版本更新说明:
3 |
4 | ## v0.2.0 @ 2017-01-05
5 |
6 | ### Feature
7 |
8 | * [Android]
9 | - 登陆
10 | - 注册
11 | - 好友
12 | - 列表及筛选
13 | - 好友信息展示
14 | - 黑名单
15 | - 好友通知
16 | - 添加好友通知展示
17 | - 接受好友请求
18 | - 拒绝好友请求
19 | - 添加好友
20 | - 群组
21 | - 群组列表
22 | - 群组成员列表
23 | - 聊天
24 | - 相机图片消息
25 | - 本地图片消息
26 | - emoji消息
27 | - 普通消息
28 |
29 | ### BugFix and Update
30 |
31 | * 群成员刷新crash的问题
32 | * 添加logout图标
33 | * 统一iOS和Android UI
34 | * emoji颜色在android颜色太浅
35 | * 登出的时候清空用户状态
36 | * 完善联系人页面的搜索在切换场景及刷新时的显示逻辑
37 |
38 | ### Extra
39 |
40 | * [react-native] 升级到最新0.39.2
41 | * [component/input] 功能完善
42 | * [component/button] 功能完善
43 | * [addContactModal] 统一通过react-native-router-flux管理modal
44 | * [tabBar] 统一通过react-native-router-flux管理tabBar
45 | * [camera] android 支持调用相机/本地图片
46 | * [yarn] 添加yarn lock file,可以通过yarn做包管理
47 |
48 | ## v0.1.0 @ 2016-12-20
49 |
50 | ### Feature
51 |
52 | * [iOS]
53 | - 登陆
54 | - 注册
55 | - 好友
56 | - 列表及筛选
57 | - 好友信息展示
58 | - 黑名单
59 | - 好友通知
60 | - 添加好友通知展示
61 | - 接受好友请求
62 | - 拒绝好友请求
63 | - 添加好友
64 | - 群组
65 | - 群组列表
66 | - 群组成员列表
67 | - 聊天
68 | - 相机图片消息
69 | - 本地图片消息
70 | - emoji消息
71 | - 普通消息
72 |
73 |
--------------------------------------------------------------------------------
/App/Lib/axios/lib/axios.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('./utils');
4 | var bind = require('./helpers/bind');
5 | var Axios = require('./core/Axios');
6 |
7 | /**
8 | * Create an instance of Axios
9 | *
10 | * @param {Object} defaultConfig The default config for the instance
11 | * @return {Axios} A new instance of Axios
12 | */
13 | function createInstance(defaultConfig) {
14 | var context = new Axios(defaultConfig);
15 | var instance = bind(Axios.prototype.request, context);
16 |
17 | // Copy axios.prototype to instance
18 | utils.extend(instance, Axios.prototype, context);
19 |
20 | // Copy context to instance
21 | utils.extend(instance, context);
22 |
23 | return instance;
24 | }
25 |
26 | // Create the default instance to be exported
27 | var axios = module.exports = createInstance();
28 |
29 | // Expose Axios class to allow class inheritance
30 | axios.Axios = Axios;
31 |
32 | // Factory for creating new instances
33 | axios.create = function create(defaultConfig) {
34 | return createInstance(defaultConfig);
35 | };
36 |
37 | // Expose all/spread
38 | axios.all = function all(promises) {
39 | return Promise.all(promises);
40 | };
41 | axios.spread = require('./helpers/spread');
42 |
--------------------------------------------------------------------------------
/ios/app/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "extent" : "full-screen",
5 | "idiom" : "iphone",
6 | "subtype" : "736h",
7 | "filename" : "Splash_iphone6p.png",
8 | "minimum-system-version" : "8.0",
9 | "orientation" : "portrait",
10 | "scale" : "3x"
11 | },
12 | {
13 | "extent" : "full-screen",
14 | "idiom" : "iphone",
15 | "subtype" : "667h",
16 | "filename" : "Splash_iphone6.png",
17 | "minimum-system-version" : "8.0",
18 | "orientation" : "portrait",
19 | "scale" : "2x"
20 | },
21 | {
22 | "orientation" : "portrait",
23 | "idiom" : "iphone",
24 | "filename" : "Splash_iphone4.png",
25 | "extent" : "full-screen",
26 | "minimum-system-version" : "7.0",
27 | "scale" : "2x"
28 | },
29 | {
30 | "extent" : "full-screen",
31 | "idiom" : "iphone",
32 | "subtype" : "retina4",
33 | "filename" : "Splash_iphone5.png",
34 | "minimum-system-version" : "7.0",
35 | "orientation" : "portrait",
36 | "scale" : "2x"
37 | }
38 | ],
39 | "info" : {
40 | "version" : 1,
41 | "author" : "xcode"
42 | }
43 | }
--------------------------------------------------------------------------------
/App/I18n/README.md:
--------------------------------------------------------------------------------
1 | # Idea
2 |
3 | Shipping app with localization for all available languages. The main idea here is to minimise the memory required of other languages that is not used by the platform.
4 |
5 | For example if the phone is localized in French, then this will only load the French and English translations into memory and ignore the 30+ other languages available.
6 |
7 | English translation is set as default fallback in case some translations are not available in the chosen language.
8 |
9 | # Installation
10 |
11 | First install i18n into your react native project
12 |
13 | npm install --save react-native-i18n
14 | react-native link
15 |
16 | Then clone this project to your within your project, removing the git repo and example afterwards.
17 |
18 | git clone --depth 1 https://github.com/hiaw/rn-translate-template translations
19 | rm -rf translations/.git translations/example
20 |
21 | Then require the translations.js file within your main app js file
22 |
23 | require('./translations/_translation.js');
24 |
25 | To use the translation in app.
26 |
27 | import I18n from 'react-native-i18n';
28 |
29 | render() {
30 | ...
31 | { I18n.t('welcome') }
32 | ...
33 | }
34 |
--------------------------------------------------------------------------------
/Tests/Sagas/TemperatureSagaTest.js:
--------------------------------------------------------------------------------
1 | import test from 'ava'
2 | import FixtureAPI from '../../App/Services/FixtureApi'
3 | import { put, call } from 'redux-saga/effects'
4 | import { getTemperature } from '../../App/Sagas/TemperatureSagas'
5 | import TemperatureActions from '../../App/Redux/TemperatureRedux'
6 |
7 | const stepper = (fn) => (mock) => fn.next(mock).value
8 |
9 | test('first calls API', (t) => {
10 | const step = stepper(getTemperature(FixtureAPI, {city: 'taco'}))
11 | // first yield is API
12 | t.deepEqual(step(), call(FixtureAPI.getCity, 'taco'))
13 | })
14 |
15 | test('success path', (t) => {
16 | const response = FixtureAPI.getCity('taco')
17 | const step = stepper(getTemperature(FixtureAPI, {city: 'taco'}))
18 | // first step API
19 | step()
20 | // Second step successful return and temperature
21 | t.deepEqual(step(response), put(TemperatureActions.temperatureSuccess(21, 'bonus')))
22 | })
23 |
24 | test('failure path', (t) => {
25 | const response = {ok: false}
26 | const step = stepper(getTemperature(FixtureAPI, {city: 'taco'}))
27 | // first step API
28 | step()
29 | // Second step failed response
30 | t.deepEqual(step(response), put(TemperatureActions.temperatureFailure()))
31 | })
32 |
--------------------------------------------------------------------------------
/App/Themes/Fonts.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | const type = {
4 | base: 'HelveticaNeue',
5 | bold: 'HelveticaNeue-Bold',
6 | emphasis: 'HelveticaNeue-Italic'
7 | }
8 |
9 | const size = {
10 | h1: 38,
11 | h2: 34,
12 | h3: 30,
13 | h4: 26,
14 | h5: 20,
15 | h6: 19,
16 | input: 18,
17 | regular: 17,
18 | medium: 14,
19 | small2: 13,
20 | small: 12,
21 | tiny1: 11,
22 | tiny: 8.5
23 | }
24 |
25 | const style = {
26 | h1: {
27 | fontFamily: type.base,
28 | fontSize: size.h1
29 | },
30 | h2: {
31 | fontWeight: 'bold',
32 | fontSize: size.h2
33 | },
34 | h3: {
35 | fontFamily: type.emphasis,
36 | fontSize: size.h3
37 | },
38 | h4: {
39 | fontFamily: type.base,
40 | fontSize: size.h4
41 | },
42 | h5: {
43 | fontFamily: type.base,
44 | fontSize: size.h5
45 | },
46 | h6: {
47 | fontFamily: type.emphasis,
48 | fontSize: size.h6
49 | },
50 | normal: {
51 | fontFamily: type.base,
52 | fontSize: size.regular
53 | },
54 | description: {
55 | fontFamily: type.base,
56 | fontSize: size.medium
57 | },
58 | rowText: {
59 | fontFamily: type.base,
60 | fontSize: size.small2
61 | }
62 | }
63 |
64 | export default {
65 | type,
66 | size,
67 | style
68 | }
69 |
70 |
--------------------------------------------------------------------------------
/Tests/Setup.js:
--------------------------------------------------------------------------------
1 | import mockery from 'mockery'
2 | import m from 'module'
3 |
4 | // inject __DEV__ as it is not available when running through the tests
5 | global.__DEV__ = true
6 |
7 | // We enable mockery and leave it on.
8 | mockery.enable()
9 |
10 | // Silence the warnings when *real* modules load... this is a change from
11 | // the norm. We want to opt-in instead of opt-out because not everything
12 | // will be mocked.
13 | mockery.warnOnUnregistered(false)
14 |
15 | // Mock any libs that get called in here
16 | // I'm looking at you react-native-router-flux, reactotron etc!
17 | mockery.registerMock('reactotron-react-native', {})
18 | mockery.registerMock('reactotron-redux', {})
19 | mockery.registerMock('reactotron-apisauce', {})
20 | mockery.registerMock('react-native-animatable', {View: 'Animatable.View'})
21 | mockery.registerMock('react-native-vector-icons/Ionicons', {})
22 |
23 | // mock i18n as it uses react native stufff
24 | mockery.registerMock('react-native-i18n', {
25 | t: (key) => key
26 | })
27 |
28 | // Mock all images for React Native
29 | const originalLoader = m._load
30 | m._load = (request, parent, isMain) => {
31 | if (request.match(/.jpeg|.jpg|.png|.gif$/)) {
32 | return { uri: request }
33 | }
34 |
35 | return originalLoader(request, parent, isMain)
36 | }
37 |
--------------------------------------------------------------------------------
/App/Sagas/index.js:
--------------------------------------------------------------------------------
1 | import { takeLatest } from 'redux-saga'
2 | import API from '../Services/Api'
3 | import FixtureAPI from '../Services/FixtureApi'
4 | import DebugSettings from '../Config/DebugSettings'
5 |
6 | /* ------------- Types ------------- */
7 |
8 | import { StartupTypes } from '../Redux/StartupRedux'
9 | import { TemperatureTypes } from '../Redux/TemperatureRedux'
10 | import { LoginTypes } from '../Redux/LoginRedux'
11 |
12 | /* ------------- Sagas ------------- */
13 |
14 | import { startup } from './StartupSagas'
15 | import { login } from './LoginSagas'
16 | import { getTemperature } from './TemperatureSagas'
17 |
18 | /* ------------- API ------------- */
19 |
20 | // The API we use is only used from Sagas, so we create it here and pass along
21 | // to the sagas which need it.
22 | const api = DebugSettings.useFixtures ? FixtureAPI : API.create()
23 |
24 | /* ------------- Connect Types To Sagas ------------- */
25 |
26 | export default function * root () {
27 | yield [
28 | // some sagas only receive an action
29 | takeLatest(StartupTypes.STARTUP, startup),
30 | takeLatest(LoginTypes.LOGIN_REQUEST, login),
31 |
32 | // some sagas receive extra parameters in addition to an action
33 | takeLatest(TemperatureTypes.TEMPERATURE_REQUEST, getTemperature, api)
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------
/App/Lib/Utilities.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | // Utility functions
4 | import { Platform } from 'react-native'
5 | import R from 'ramda'
6 |
7 | // useful cleaning functions
8 | const nullToEmpty = R.defaultTo('')
9 | const replaceEscapedCRLF = R.replace(/\\n/g)
10 | const nullifyNewlines = R.compose(replaceEscapedCRLF(' '), nullToEmpty)
11 |
12 | // Correct Map URIs
13 | export const locationURL = (address: string) => {
14 | let cleanAddress = nullifyNewlines(address)
15 | // https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html
16 | let url = `http://maps.apple.com/?address=${cleanAddress}`
17 | // https://developers.google.com/maps/documentation/ios-sdk/urlscheme
18 | if (Platform.OS === 'android') url = `http://maps.google.com/?q=${cleanAddress}`
19 |
20 | return url
21 | }
22 | export const directionsURL = (address: string) => {
23 | let cleanAddress = nullifyNewlines(address)
24 | // https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html
25 | let url = `http://maps.apple.com/?daddr=${cleanAddress}&dirflg=d`
26 | // https://developers.google.com/maps/documentation/ios-sdk/urlscheme
27 | if (Platform.OS === 'android') url = `http://maps.google.com/?daddr=${cleanAddress}`
28 |
29 | return url
30 | }
31 |
--------------------------------------------------------------------------------
/App/Services/RehydrationServices.js:
--------------------------------------------------------------------------------
1 | import ReduxPersist from '../Config/ReduxPersist'
2 | import { AsyncStorage } from 'react-native'
3 | import { persistStore } from 'redux-persist'
4 | import StartupActions from '../Redux/StartupRedux'
5 |
6 | const updateReducers = (store: Object) => {
7 | const reducerVersion = ReduxPersist.reducerVersion
8 | const config = ReduxPersist.storeConfig
9 | const startup = () => store.dispatch(StartupActions.startup())
10 |
11 | // Check to ensure latest reducer version
12 | AsyncStorage.getItem('reducerVersion').then((localVersion) => {
13 | if (localVersion !== reducerVersion) {
14 | console.tron.display({
15 | name: 'PURGE',
16 | value: {
17 | 'Old Version:': localVersion,
18 | 'New Version:': reducerVersion
19 | },
20 | preview: 'Reducer Version Change Detected',
21 | important: true
22 | })
23 | // Purge store
24 | persistStore(store, config, startup).purge()
25 | AsyncStorage.setItem('reducerVersion', reducerVersion)
26 | } else {
27 | persistStore(store, config, startup)
28 | }
29 | }).catch(() => {
30 | persistStore(store, config, startup)
31 | AsyncStorage.setItem('reducerVersion', reducerVersion)
32 | })
33 | }
34 |
35 | export default {updateReducers}
36 |
--------------------------------------------------------------------------------
/App/Config/PushConfig.js:
--------------------------------------------------------------------------------
1 | import PushNotification from 'react-native-push-notification'
2 |
3 | // https://github.com/zo0r/react-native-push-notification
4 | PushNotification.configure({
5 |
6 | // (optional) Called when Token is generated (iOS and Android)
7 | onRegister: (token) => {
8 | if (__DEV__) console.log('TOKEN:', token)
9 | },
10 |
11 | // (required) Called when a remote or local notification is opened or received
12 | onNotification: (notification) => {
13 | if (__DEV__) console.log('NOTIFICATION:', notification)
14 | },
15 |
16 | // ANDROID ONLY: (optional) GCM Sender ID.
17 | senderID: 'YOUR GCM SENDER ID',
18 |
19 | // IOS ONLY (optional): default: all - Permissions to register.
20 | permissions: {
21 | alert: true,
22 | badge: true,
23 | sound: true
24 | },
25 |
26 | // Should the initial notification be popped automatically
27 | // default: true
28 | // Leave this off unless you have good reason.
29 | popInitialNotification: false,
30 |
31 | /**
32 | * IOS ONLY: (optional) default: true
33 | * - Specified if permissions will requested or not,
34 | * - if not, you must call PushNotificationsHandler.requestPermissions() later
35 | * This example app shows how to best call requestPermissions() later.
36 | */
37 | requestPermissions: false
38 | })
39 |
--------------------------------------------------------------------------------
/App/Components/Styles/InputStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import {StyleSheet} from 'react-native'
4 | import {Fonts, Colors} from '../../Themes/'
5 |
6 | export default StyleSheet.create({
7 | search: {
8 | borderRadius: 3,
9 | flexDirection: 'row',
10 | borderWidth: StyleSheet.hairlineWidth,
11 | borderColor: Colors.coolGrey,
12 | paddingVertical: 17,
13 | paddingHorizontal: 15,
14 | },
15 | searchFocus: {
16 | borderColor: Colors.frogGreen
17 | },
18 | iconSize: 13,
19 | searchRow: {
20 | // color: Colors.blueyGrey,
21 | flex: 1,
22 | height: 30,
23 | justifyContent: 'center',
24 | alignItems: 'flex-start',
25 | backgroundColor: Colors.paleGrey,
26 | flexDirection: 'column',
27 | // borderWidth: 1
28 | },
29 | searchInput: {
30 | // height: 30,
31 | flex: 1,
32 | alignSelf: 'stretch',
33 | fontSize: 13,
34 | paddingLeft: 4,
35 | paddingVertical: 5
36 | },
37 | searchIcon: {
38 | alignItems: 'flex-end',
39 | justifyContent: 'center',
40 | },
41 | searchIconFocus: {
42 | flex: 0,
43 | width: 20,
44 | alignItems: 'center'
45 | },
46 | searchCancel: {
47 | width: 50,
48 | height: 30,
49 | alignItems: 'center',
50 | justifyContent: 'center',
51 | },
52 | // placeholderTextColor: Colors.blueGrey,
53 | })
54 |
--------------------------------------------------------------------------------
/App/Containers/RootContainer.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import React, { Component } from 'react'
4 | import { View, StatusBar } from 'react-native'
5 | import NavigationRouter from '../Navigation/NavigationRouter'
6 | import { connect } from 'react-redux'
7 | import StartupActions from '../Redux/StartupRedux'
8 | import ReduxPersist from '../Config/ReduxPersist'
9 |
10 | // Styles
11 | import styles from './Styles/RootContainerStyle'
12 |
13 | // import WebIM from '../Lib/WebIM'
14 | // import WebIMActions from '../Redux/WebIMRedux'
15 |
16 | class RootContainer extends Component {
17 |
18 | componentDidMount () {
19 | // if redux persist is not active fire startup action
20 | if (!ReduxPersist.active) {
21 | this.props.startup()
22 | }
23 | }
24 |
25 | componentWillReceiveProps (nextProps) {
26 | console.log('componentWillReceiveProps', nextProps)
27 | }
28 |
29 | render () {
30 | return (
31 |
32 | {/* barStyle='light-content' */}
33 |
34 |
35 |
36 | )
37 | }
38 | }
39 |
40 | const mapStateToDispatch = (dispatch) => ({
41 | startup: () => dispatch(StartupActions.startup())
42 | // dispatch: dispatch
43 | })
44 |
45 | export default connect(null, mapStateToDispatch)(RootContainer)
46 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
23 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/App/Components/ModalHeader.js:
--------------------------------------------------------------------------------
1 | import React, {Component, PropTypes} from 'react'
2 | import {connect} from 'react-redux'
3 | import {Modal, Text, TouchableOpacity, View, Dimensions} from 'react-native'
4 |
5 | // custom
6 | import I18n from 'react-native-i18n'
7 | import {Images, Colors} from '../Themes'
8 | import Styles from './Styles/ModalHeaderStyle'
9 | import Icon from 'react-native-vector-icons/FontAwesome';
10 |
11 | export default class ModalHeader extends Component {
12 |
13 | // ------------ init -------------
14 | constructor(props) {
15 | super(props)
16 | }
17 |
18 | // ------------ lifecycle ------------
19 |
20 |
21 | // ------------ renders -------------
22 |
23 | render() {
24 | let {title = 'Title', leftBtn, leftClick, rightBtn, rightClick} = this.props
25 |
26 | return (
27 |
28 |
29 |
30 | {leftBtn}
31 |
32 |
33 |
34 | {title}
35 |
36 |
37 |
38 | {rightBtn}
39 |
40 |
41 |
42 | )
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/App/Components/Styles/InfoNavBarStyle.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import {Colors, Metrics} from '../../Themes'
3 | import {create} from '../../Lib/PlatformStyleSheet'
4 |
5 | export default create({
6 | container: {
7 | position: 'absolute',
8 | top: 0,
9 | left: 0,
10 | right: 0,
11 | height: Metrics.navBarHeight,
12 | // paddingHorizontal: Metrics.baseMargin,
13 | // backgroundColor: 'transparent',
14 | flexDirection: 'row',
15 | alignItems: 'center',
16 | justifyContent: 'space-between',
17 | //
18 | ios: {
19 | paddingTop: 30,
20 | },
21 | backgroundColor: Colors.white1,
22 | borderBottomWidth: StyleSheet.hairlineWidth,
23 | borderBottomColor: Colors.paleGrey
24 | },
25 | leftButton: {
26 | paddingHorizontal: 15,
27 | paddingVertical: 3,
28 | },
29 | logo: {
30 | height: Metrics.navBarHeight - Metrics.doubleBaseMargin,
31 | width: Metrics.navBarHeight - Metrics.doubleBaseMargin,
32 | resizeMode: 'contain'
33 | },
34 | rightButton: {
35 | paddingHorizontal: 15,
36 | paddingVertical: 3,
37 | },
38 | title: {
39 | flex: 1,
40 | textAlign: 'center',
41 | flexDirection: 'row',
42 | },
43 | flexLeft: {
44 | flex: 1,
45 | justifyContent: 'flex-start',
46 | flexDirection: 'row',
47 | },
48 | flexRight: {
49 | flex: 1,
50 | justifyContent: 'flex-end',
51 | flexDirection: 'row',
52 | }
53 | })
54 |
--------------------------------------------------------------------------------
/App/Components/Button.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import React from 'react'
4 | import {View, TouchableOpacity, Text, TouchableNativeFeedback, Platform} from 'react-native'
5 | import {Colors, Metrics} from '../Themes'
6 | import Styles from './Styles/ButtonStyle'
7 |
8 | export default class Button extends React.Component {
9 | render() {
10 | const {color, isHighlight = false, styles} = this.props
11 |
12 | // const Touchable = Platform.OS === 'android' ? : TouchableOpacity;
13 |
14 | let textStyles = [];
15 | color && textStyles.push({color: color})
16 |
17 | let textWrapperStyles = [Styles.button, styles, {
18 | // borderWidth: 1,
19 | justifyContent: 'center',
20 | }]
21 | textWrapperStyles.push({backgroundColor: isHighlight ? Colors.buttonGreen : Colors.coolGrey})
22 |
23 | return Platform.OS === 'android' ? (
24 |
27 |
28 | {this.props.text}
29 |
30 |
31 | ) : (
32 |
34 |
35 | {this.props.text}
36 |
37 |
38 | )
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/App/Services/ImmutablePersistenceTransform.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import R from 'ramda'
4 | import Immutable from 'seamless-immutable'
5 |
6 | // is this object already Immutable?
7 | const isImmutable = R.has('asMutable')
8 |
9 | // change this Immutable object into a JS object
10 | const convertToJs = (state: Object) => state.asMutable({deep: true})
11 |
12 | // optionally convert this object into a JS object if it is Immutable
13 | const fromImmutable = R.when(isImmutable, convertToJs)
14 |
15 | // convert this JS object into an Immutable object
16 | const toImmutable = (raw: Object) => Immutable(raw)
17 |
18 | // the transform interface that redux-persist is expecting
19 | export default {
20 | out: (state: Object) => {
21 | console.log('retrieving', state)
22 | // --- HACKZORZ ---
23 | // Attach a empty-ass function to the object called `mergeDeep`.
24 | // This tricks redux-persist into just placing our Immutable object into the state tree
25 | // instead of trying to convert it to a POJO
26 | // https://github.com/rt2zz/redux-persist/blob/master/src/autoRehydrate.js#L55
27 | //
28 | // Another equal terrifying option would be to try to pass their other check
29 | // which is lodash isPlainObject.
30 | // --- END HACKZORZ ---
31 | state.mergeDeep = R.identity
32 | return toImmutable(state)
33 | },
34 | in: (raw: Object) => {
35 | // console.log({ storing: raw })
36 | return fromImmutable(raw)
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/App/Redux/DemoRedux.js:
--------------------------------------------------------------------------------
1 | import {createReducer, createActions} from 'reduxsauce'
2 | import Immutable from 'seamless-immutable'
3 |
4 | /* ------------- Types and Action Creators ------------- */
5 |
6 | const {Types, Creators} = createActions({
7 | nop: [''],
8 | nopFunc: null,
9 | asyncFunc: () => {
10 | return (dispatch, getState) => {
11 |
12 | }
13 | }
14 | })
15 |
16 | export const DemoTypes = Types
17 | export default Creators
18 |
19 | /* ------------- Initial State ------------- */
20 |
21 | export const INITIAL_STATE = Immutable({
22 | error: null,
23 | fetching: false,
24 | })
25 |
26 | /* ------------- Reducers ------------- */
27 |
28 | export const request = (state, {username, password}) => {
29 | return state.merge({fetching: true, error: false})
30 | }
31 |
32 | export const success = (state, {msg}) => {
33 | return state.merge({fetching: false, error: false, msg})
34 | }
35 |
36 | export const failure = (state, {error}) => {
37 | return state.merge({fetching: false, error: true})
38 | }
39 |
40 | // we've logged out
41 | export const logout = (state) => INITIAL_STATE
42 |
43 | /* ------------- Hookup Reducers To Types ------------- */
44 |
45 | export const reducer = createReducer(INITIAL_STATE, {
46 | [Types.NOP]: request,
47 | [Types.NOP_FUNC]: request,
48 | })
49 |
50 | /* ------------- Selectors ------------- */
51 |
52 | // Is the current user logged in?
53 | export const isLoggedIn = (loginState) => loginState.username !== null
54 |
--------------------------------------------------------------------------------
/App/Containers/Styles/ThemeScreenStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { StyleSheet } from 'react-native'
4 | import { Colors, Metrics, ApplicationStyles } from '../../Themes/'
5 |
6 | export default StyleSheet.create({
7 | ...ApplicationStyles.screen,
8 | groupContainer: {
9 | ...ApplicationStyles.groupContainer
10 | },
11 | sectionHeaderContainer: {
12 | ...ApplicationStyles.darkLabelContainer
13 | },
14 | sectionHeader: {
15 | ...ApplicationStyles.darkLabel
16 | },
17 | colorsContainer: {
18 | flexDirection: 'row',
19 | flexWrap: 'wrap',
20 | justifyContent: 'center'
21 | },
22 | backgroundContainer: {
23 | position: 'relative',
24 | width: 102,
25 | height: 102,
26 | borderWidth: 1,
27 | borderColor: Colors.frost
28 | },
29 | backerImage: {
30 | top: 0,
31 | bottom: 0,
32 | left: 0,
33 | right: 0,
34 | position: 'absolute',
35 | resizeMode: 'stretch'
36 | },
37 | colorContainer: {
38 | height: 130,
39 | padding: Metrics.smallMargin,
40 | marginBottom: Metrics.smallMargin
41 | },
42 | colorSquare: {
43 | width: 100,
44 | height: 100
45 | },
46 | colorName: {
47 | width: 100,
48 | height: Metrics.doubleBaseMargin,
49 | lineHeight: Metrics.doubleBaseMargin,
50 | color: Colors.charcoal,
51 | textAlign: 'center'
52 | },
53 | fontRow: {
54 | padding: Metrics.smallMargin,
55 | marginHorizontal: Metrics.smallMargin,
56 | color: Colors.snow
57 | }
58 | })
59 |
--------------------------------------------------------------------------------
/App/Components/MapCallout.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Text, TouchableOpacity } from 'react-native'
3 | import MapView from 'react-native-maps'
4 | import Styles from './Styles/MapCalloutStyle'
5 | import ExamplesRegistry from '../Services/ExamplesRegistry'
6 |
7 | // Example
8 | ExamplesRegistry.add('Map Callout', () =>
9 | window.alert('That tickles!')}
14 | />
15 | )
16 |
17 | type MapCalloutProps = {
18 | location: Object,
19 | onPress: () => void
20 | }
21 |
22 | export default class MapCallout extends React.Component {
23 | props: MapCalloutProps
24 |
25 | constructor (props: MapCalloutProps) {
26 | super(props)
27 | this.onPress = this.props.onPress.bind(this, this.props.location)
28 | }
29 |
30 | render () {
31 | /* ***********************************************************
32 | * Customize the appearance of the callout that opens when the user interacts with a marker.
33 | * Note: if you don't want your callout surrounded by the default tooltip, pass `tooltip={true}` to `MapView.Callout`
34 | *************************************************************/
35 | const { location } = this.props
36 | return (
37 |
38 |
39 | {location.title}
40 |
41 |
42 | )
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/App/Lib/axios/lib/core/InterceptorManager.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('./../utils');
4 |
5 | function InterceptorManager() {
6 | this.handlers = [];
7 | }
8 |
9 | /**
10 | * Add a new interceptor to the stack
11 | *
12 | * @param {Function} fulfilled The function to handle `then` for a `Promise`
13 | * @param {Function} rejected The function to handle `reject` for a `Promise`
14 | *
15 | * @return {Number} An ID used to remove interceptor later
16 | */
17 | InterceptorManager.prototype.use = function use(fulfilled, rejected) {
18 | this.handlers.push({
19 | fulfilled: fulfilled,
20 | rejected: rejected
21 | });
22 | return this.handlers.length - 1;
23 | };
24 |
25 | /**
26 | * Remove an interceptor from the stack
27 | *
28 | * @param {Number} id The ID that was returned by `use`
29 | */
30 | InterceptorManager.prototype.eject = function eject(id) {
31 | if (this.handlers[id]) {
32 | this.handlers[id] = null;
33 | }
34 | };
35 |
36 | /**
37 | * Iterate over all the registered interceptors
38 | *
39 | * This method is particularly useful for skipping over any
40 | * interceptors that may have become `null` calling `eject`.
41 | *
42 | * @param {Function} fn The function to call for each interceptor
43 | */
44 | InterceptorManager.prototype.forEach = function forEach(fn) {
45 | utils.forEach(this.handlers, function forEachHandler(h) {
46 | if (h !== null) {
47 | fn(h);
48 | }
49 | });
50 | };
51 |
52 | module.exports = InterceptorManager;
53 |
--------------------------------------------------------------------------------
/ios/app/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 "RCTBundleURLProvider.h"
13 | #import "RCTRootView.h"
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:@"app"
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 |
--------------------------------------------------------------------------------
/App/Redux/GroupMemberRedux.js:
--------------------------------------------------------------------------------
1 | import {createReducer, createActions} from 'reduxsauce'
2 | import Immutable from 'seamless-immutable'
3 |
4 | /* ------------- Types and Action Creators ------------- */
5 |
6 | const {Types, Creators} = createActions({
7 | updateGroupMember: ['id', 'members'],
8 | // ---------------async------------------
9 | getGroupMember: (id) => {
10 | return (dispatch, getState) => {
11 | WebIM.conn.queryRoomMember({
12 | roomId: id,
13 | success: function (members) {
14 | dispatch(Creators.updateGroupMember(id, members))
15 | },
16 | error: function () {
17 | }
18 | });
19 | }
20 | },
21 | })
22 |
23 | export const GroupMemberTypes = Types
24 | export default Creators
25 |
26 | /* ------------- Initial State ------------- */
27 |
28 | export const INITIAL_STATE = Immutable({})
29 |
30 | /* ------------- Reducers ------------- */
31 | // [{jid,name,roomId}] members
32 | export const updateGroupMember = (state, {id, members}) => {
33 | let byName = {}
34 | members.forEach((v) => {
35 | let name = (v.jid.match(/_(.*?)@/))[1]
36 | byName[name] = v
37 | })
38 | return state.merge({
39 | [id]: {
40 | byName,
41 | names: Object.keys(byName).sort()
42 | }
43 | })
44 | }
45 |
46 | /* ------------- Hookup Reducers To Types ------------- */
47 |
48 | export const reducer = createReducer(INITIAL_STATE, {
49 | [Types.UPDATE_GROUP_MEMBER]: updateGroupMember,
50 | })
51 |
52 | /* ------------- Selectors ------------- */
53 |
--------------------------------------------------------------------------------
/App/Redux/TemperatureRedux.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { createReducer, createActions } from 'reduxsauce'
4 | import Immutable from 'seamless-immutable'
5 |
6 | /* ------------- Types and Action Creators ------------- */
7 |
8 | const { Types, Creators } = createActions({
9 | temperatureRequest: ['city'],
10 | temperatureSuccess: ['temperature'],
11 | temperatureFailure: null
12 | })
13 |
14 | export const TemperatureTypes = Types
15 | export default Creators
16 |
17 | /* ------------- Initial State ------------- */
18 |
19 | export const INITIAL_STATE = Immutable({
20 | temperature: null,
21 | fetching: null,
22 | error: null,
23 | city: null
24 | })
25 |
26 | /* ------------- Reducers ------------- */
27 |
28 | // request the temperature for a city
29 | export const request = (state: Object, { city }: Object) =>
30 | state.merge({ fetching: true, city, temperature: null })
31 |
32 | // successful temperature lookup
33 | export const success = (state: Object, action: Object) => {
34 | const { temperature } = action
35 | return state.merge({ fetching: false, error: null, temperature })
36 | }
37 |
38 | // failed to get the temperature
39 | export const failure = (state: Object) =>
40 | state.merge({ fetching: false, error: true, temperature: null })
41 |
42 | /* ------------- Hookup Reducers To Types ------------- */
43 |
44 | export const reducer = createReducer(INITIAL_STATE, {
45 | [Types.TEMPERATURE_REQUEST]: request,
46 | [Types.TEMPERATURE_SUCCESS]: success,
47 | [Types.TEMPERATURE_FAILURE]: failure
48 | })
49 |
--------------------------------------------------------------------------------
/Tests/Components/RoundedButtonTest.js:
--------------------------------------------------------------------------------
1 | // https://github.com/airbnb/enzyme/blob/master/docs/api/shallow.md
2 | import test from 'ava'
3 | import React from 'react'
4 | import RoundedButton from '../../App/Components/RoundedButton'
5 | import { shallow } from 'enzyme'
6 |
7 | // Basic wrapper
8 | const wrapper = shallow( {}} text='howdy' />)
9 |
10 | test('component exists', (t) => {
11 | t.is(wrapper.length, 1) // exists
12 | })
13 |
14 | test('component structure', (t) => {
15 | t.is(wrapper.name(), 'TouchableOpacity') // the right root component
16 | t.is(wrapper.children().length, 1) // has 1 child
17 | t.is(wrapper.children().first().name(), 'Text') // that child is Text
18 | })
19 |
20 | test('the text is set properly - uppercase', (t) => {
21 | t.is(wrapper.children().first().props().children, 'HOWDY')
22 | })
23 |
24 | test('onPress', (t) => {
25 | let i = 0 // i guess i could have used sinon here too... less is more i guess
26 | const onPress = () => i++
27 | const wrapperPress = shallow()
28 |
29 | t.is(wrapperPress.prop('onPress'), onPress) // uses the right handler
30 | t.is(i, 0)
31 | wrapperPress.simulate('press')
32 | t.is(i, 1)
33 | })
34 |
35 | test('renders children text when passed', (t) => {
36 | const wrapperChild = shallow( {}}>Howdy)
37 | t.is(wrapperChild.children().length, 1) // has 1 child
38 | t.is(wrapperChild.children().first().name(), 'Text') // that child is Text
39 | })
40 |
--------------------------------------------------------------------------------
/App/Containers/Styles/DeviceInfoScreenStyle.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import { StyleSheet } from 'react-native'
4 | import { Colors, Metrics, Fonts, ApplicationStyles } from '../../Themes/'
5 |
6 | export default StyleSheet.create({
7 | ...ApplicationStyles.screen,
8 | cardTitle: {
9 | alignSelf: 'center',
10 | fontSize: Fonts.size.regular,
11 | fontWeight: 'bold',
12 | marginVertical: Metrics.baseMargin,
13 | color: Colors.snow
14 | },
15 | cardContainer: {
16 | backgroundColor: Colors.ember,
17 | borderColor: 'black',
18 | borderWidth: 1,
19 | borderRadius: 2,
20 | shadowColor: Colors.panther,
21 | shadowOffset: {
22 | height: 7,
23 | width: 7
24 | },
25 | shadowRadius: 2,
26 | paddingBottom: Metrics.baseMargin,
27 | margin: Metrics.baseMargin
28 | },
29 | rowContainer: {
30 | flexDirection: 'row',
31 | borderColor: Colors.windowTint,
32 | borderWidth: 0.5,
33 | borderRadius: 2,
34 | marginHorizontal: Metrics.baseMargin
35 | },
36 | rowLabelContainer: {
37 | flex: 1,
38 | justifyContent: 'center',
39 | backgroundColor: Colors.snow
40 | },
41 | rowLabel: {
42 | fontWeight: 'bold',
43 | fontSize: Fonts.size.medium,
44 | marginVertical: Metrics.baseMargin,
45 | marginLeft: Metrics.baseMargin
46 | },
47 | rowInfoContainer: {
48 | flex: 2,
49 | justifyContent: 'center',
50 | backgroundColor: Colors.silver
51 | },
52 | rowInfo: {
53 | fontSize: Fonts.size.regular,
54 | margin: Metrics.baseMargin
55 | }
56 | })
57 |
--------------------------------------------------------------------------------
/App/Lib/MapHelpers.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import R from 'ramda'
4 |
5 | export const removeEmpty = (markers: Array