From 274250df8257da7ed9b9eafb5dfd9941605654f1 Mon Sep 17 00:00:00 2001 From: Terry Sahaidak Date: Wed, 24 Feb 2016 19:08:40 +0200 Subject: [PATCH 1/6] Add base gitter-faye native module --- android/app/build.gradle | 1 + .../java/com/gittermobile/MainActivity.java | 5 +- android/settings.gradle | 3 +- libs/react-native-gitter-faye/README.md | 21 +++ libs/react-native-gitter-faye/build.gradle | 42 ++++++ .../react-native-gitter-faye/index.android.js | 2 + libs/react-native-gitter-faye/package.json | 11 ++ .../src/main/AndroidManifest.xml | 4 + .../terrysahaidak/faye/FayeGitterModule.java | 138 ++++++++++++++++++ .../terrysahaidak/faye/FayeGitterPackage.java | 42 ++++++ 10 files changed, 267 insertions(+), 2 deletions(-) create mode 100644 libs/react-native-gitter-faye/README.md create mode 100644 libs/react-native-gitter-faye/build.gradle create mode 100644 libs/react-native-gitter-faye/index.android.js create mode 100644 libs/react-native-gitter-faye/package.json create mode 100644 libs/react-native-gitter-faye/src/main/AndroidManifest.xml create mode 100644 libs/react-native-gitter-faye/src/main/java/com/terrysahaidak/faye/FayeGitterModule.java create mode 100644 libs/react-native-gitter-faye/src/main/java/com/terrysahaidak/faye/FayeGitterPackage.java diff --git a/android/app/build.gradle b/android/app/build.gradle index 7d9039f..c726fa0 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -123,4 +123,5 @@ dependencies { compile "com.android.support:appcompat-v7:23.0.1" compile "com.facebook.react:react-native:0.20.+" compile project(':ExtraDimensions') + compile project(':react-native-gitter-faye') } diff --git a/android/app/src/main/java/com/gittermobile/MainActivity.java b/android/app/src/main/java/com/gittermobile/MainActivity.java index 5b25287..1fc0747 100644 --- a/android/app/src/main/java/com/gittermobile/MainActivity.java +++ b/android/app/src/main/java/com/gittermobile/MainActivity.java @@ -9,6 +9,8 @@ import ca.jaysoo.extradimensions.ExtraDimensionsPackage; +import com.terrysahaidak.faye.FayeGitterPackage; + public class MainActivity extends ReactActivity { /** * Returns the name of the main component registered from JavaScript. @@ -36,7 +38,8 @@ protected boolean getUseDeveloperSupport() { protected List getPackages() { return Arrays.asList( new MainReactPackage(), - new ExtraDimensionsPackage(this) + new ExtraDimensionsPackage(this), + new FayeGitterPackage() ); } } diff --git a/android/settings.gradle b/android/settings.gradle index 56ed95e..d7f105b 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,4 +1,5 @@ rootProject.name = 'gittermobile' -include ':app', ':ExtraDimensions' +include ':app', ':ExtraDimensions', ':react-native-gitter-faye' +project(':react-native-gitter-faye').projectDir = new File(rootProject.projectDir, '../libs/react-native-gitter-faye') project(':ExtraDimensions').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-extra-dimensions-android/android') diff --git a/libs/react-native-gitter-faye/README.md b/libs/react-native-gitter-faye/README.md new file mode 100644 index 0000000..0c9c460 --- /dev/null +++ b/libs/react-native-gitter-faye/README.md @@ -0,0 +1,21 @@ +## react-native-gitter-faye + +#### example +``` +FayeGitter.setAccessToken('token') +FayeGitter.create() + +FayeGitter.connect().then(() => { + FayeGitter.subscribe('/api/v1/user/555e610f15522ed4b3e0c169/rooms') + FayeGitter.logger() +}) + +// events +FayeGitter:onDisconnected +FayeGitter:onFailedToCreate +FayeGitter:Message +FayeGitter:SubscribtionFailed +FayeGitter:Subscribed +FayeGitter:Unsubscribed +FayeGitter:log +``` diff --git a/libs/react-native-gitter-faye/build.gradle b/libs/react-native-gitter-faye/build.gradle new file mode 100644 index 0000000..b59f3d8 --- /dev/null +++ b/libs/react-native-gitter-faye/build.gradle @@ -0,0 +1,42 @@ +buildscript { + repositories { + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:1.1.3' + } +} + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.1" + + defaultConfig { + minSdkVersion 16 + targetSdkVersion 22 + versionCode 1 + versionName "1.0" + } + lintOptions { + abortOnError false + } +} + +repositories { + mavenCentral() +} + +dependencies { + compile 'com.facebook.react:react-native:0.20.+' +} + +repositories { + jcenter() +} + +dependencies { + compile 'com.github.amatkivskiy:gitter.sdk.async:1.5' +} diff --git a/libs/react-native-gitter-faye/index.android.js b/libs/react-native-gitter-faye/index.android.js new file mode 100644 index 0000000..f0dc3f7 --- /dev/null +++ b/libs/react-native-gitter-faye/index.android.js @@ -0,0 +1,2 @@ +var { NativeModules } = require('react-native'); +module.exports = NativeModules.FayeGitter; diff --git a/libs/react-native-gitter-faye/package.json b/libs/react-native-gitter-faye/package.json new file mode 100644 index 0000000..315d86f --- /dev/null +++ b/libs/react-native-gitter-faye/package.json @@ -0,0 +1,11 @@ +{ + "name": "react-native-faye", + "version": "1.0.0", + "description": "", + "main": "index.android.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} diff --git a/libs/react-native-gitter-faye/src/main/AndroidManifest.xml b/libs/react-native-gitter-faye/src/main/AndroidManifest.xml new file mode 100644 index 0000000..4d0e6e1 --- /dev/null +++ b/libs/react-native-gitter-faye/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + diff --git a/libs/react-native-gitter-faye/src/main/java/com/terrysahaidak/faye/FayeGitterModule.java b/libs/react-native-gitter-faye/src/main/java/com/terrysahaidak/faye/FayeGitterModule.java new file mode 100644 index 0000000..c28877b --- /dev/null +++ b/libs/react-native-gitter-faye/src/main/java/com/terrysahaidak/faye/FayeGitterModule.java @@ -0,0 +1,138 @@ +package com.terrysahaidak.faye; + +import com.google.gson.JsonObject; +import javax.annotation.Nullable; + +import com.amatkivskiy.gitter.sdk.async.faye.client.AsyncGitterFayeClient; +import com.amatkivskiy.gitter.sdk.async.faye.interfaces.ChannelListener; +import com.amatkivskiy.gitter.sdk.async.faye.interfaces.ConnectionListener; +import com.amatkivskiy.gitter.sdk.async.faye.interfaces.DisconnectionListener; +import com.amatkivskiy.gitter.sdk.async.faye.interfaces.Logger; +import com.amatkivskiy.gitter.sdk.async.faye.interfaces.DisconnectionListener; +import com.amatkivskiy.gitter.sdk.async.faye.interfaces.FailListener; + +import com.facebook.react.bridge.*; +import com.facebook.react.modules.core.DeviceEventManagerModule; + + +public class FayeGitterModule extends ReactContextBaseJavaModule { + private static String accessToken; + private static AsyncGitterFayeClient client; + + public FayeGitterModule(ReactApplicationContext reactContext) { + super(reactContext); + } + + @Override + public String getName() { + return "FayeGitter"; + } + + private String getAccessToken() { + return accessToken; + } + + private void sendEvent(String eventName, @Nullable Object params) { + getReactApplicationContext() + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit(eventName, params); + } + + private void sendEvent(String eventName, String message) { + getReactApplicationContext() + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit(eventName, message); + } + + @ReactMethod + public void setAccessToken(String token) { + accessToken = token; + } + + @ReactMethod + public void create() { + this.client = new AsyncGitterFayeClient( + getAccessToken(), + new DisconnectionListener() { + @Override + public void onDisconnected() { + sendEvent("FayeGitter:onDisconnected", "Disconected"); + } + }, + new FailListener() { + @Override + public void onFailed(Exception ex) { + sendEvent("FayeGitter:onFailedToCreate", "Failed to create client: " + ex.getMessage()); + } + } + ); + } + + @ReactMethod + public void connect(final Promise promise) { + this.client.connect(new ConnectionListener() { + @Override + public void onConnected() { + promise.resolve(true); + } + }); + } + + @ReactMethod + public void subscribe(String channelName) { + this.client.subscribe(channelName, new ChannelListener() { + @Override + public void onMessage(String channel, JsonObject message) { + System.out.println(message); + WritableMap params = new WritableNativeMap(); + params.putString("channel", channel); + params.putString("json", message.toString()); + sendEvent("FayeGitter:Message", params); + } + + @Override + public void onFailed(String channel, Exception ex) { + WritableMap params = new WritableNativeMap(); + params.putString("channel", channel); + params.putString("Exception", ex.getMessage()); + sendEvent("FayeGitter:SubscribtionFailed", params); + } + @Override + public void onSubscribed(String channel) { + WritableMap params = new WritableNativeMap(); + params.putString("channel", channel); + sendEvent("FayeGitter:Subscribed", params); + } + + @Override + public void onUnSubscribed(String channel) { + WritableMap params = new WritableNativeMap(); + params.putString("channel", channel); + sendEvent("FayeGitter:Unsubscribed", params); + } + }); + } + + @ReactMethod + public void unsubscribe(String channel) { + this.client.unSubscribe(channel); + } + + @ReactMethod + public void disconnect() { + this.client.disconnect(); + } + + @ReactMethod + public void logger() { + this.client.setLogger(new Logger() { + @Override + public void log(String message) { + System.out.println(message); + WritableMap params = new WritableNativeMap(); + params.putString("log", message); + sendEvent("FayeGitter:log", params); + } + }); + } +} diff --git a/libs/react-native-gitter-faye/src/main/java/com/terrysahaidak/faye/FayeGitterPackage.java b/libs/react-native-gitter-faye/src/main/java/com/terrysahaidak/faye/FayeGitterPackage.java new file mode 100644 index 0000000..dc517a2 --- /dev/null +++ b/libs/react-native-gitter-faye/src/main/java/com/terrysahaidak/faye/FayeGitterPackage.java @@ -0,0 +1,42 @@ +package com.terrysahaidak.faye; + +import android.app.Activity; + +import com.facebook.react.ReactPackage; +import com.facebook.react.bridge.JavaScriptModule; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.ViewManager; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Created by Nishanth Shankar on 9/23/15. + */ +public class FayeGitterPackage implements ReactPackage { + private Activity mActivity = null; + + public FayeGitterPackage(){ + + } + + @Override + public List createNativeModules(ReactApplicationContext reactApplicationContext) { + List modules = new ArrayList(); + modules.add(new FayeGitterModule(reactApplicationContext)); + return modules; + } + + @Override + public List> createJSModules() { + return Collections.emptyList(); + } + + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + return Arrays.asList(); + } +} From 9e0c466b24b5e57899adc1598c2af50e6b99e717 Mon Sep 17 00:00:00 2001 From: Terry Sahaidak Date: Thu, 25 Feb 2016 01:15:46 +0200 Subject: [PATCH 2/6] Add base realtime functionality --- app/main.js | 2 +- app/modules/app.js | 96 ++++++++++++++++++++++++++++++++++++++++++++ app/modules/auth.js | 2 +- app/modules/index.js | 2 + app/modules/init.js | 31 -------------- app/modules/rooms.js | 39 +++++++++++++++++- 6 files changed, 138 insertions(+), 34 deletions(-) create mode 100644 app/modules/app.js delete mode 100644 app/modules/init.js diff --git a/app/main.js b/app/main.js index c6dd36c..9d0256e 100644 --- a/app/main.js +++ b/app/main.js @@ -3,7 +3,7 @@ import {Provider} from 'react-redux' import configureStore from './configureStore' import App from './screens' -import {init} from './modules/init' +import {init} from './modules/app' const store = configureStore() diff --git a/app/modules/app.js b/app/modules/app.js new file mode 100644 index 0000000..5da026c --- /dev/null +++ b/app/modules/app.js @@ -0,0 +1,96 @@ +import {getItem, removeItem} from '../utils/storage' +import {getCurrentUser} from './viewer' +import {getRooms, getSuggestedRooms, subscribeToRooms, updateRoomState} from './rooms' +import FayeGitter from '../../libs/react-native-gitter-faye' +import {DeviceEventEmitter} from 'react-native' + +/** + * Constants + */ + +export const INITIALIZED = 'app/INITIALIZED' +export const CHANGE_NET_STATUS = 'app/CHANGE_NET_STATUS' +export const CHANGE_APP_STATE = 'app/CHANGE_APP_STATE' + +/** + * Action Creators + */ + +export function init() { + return async (dispatch, getState) => { + try { + const token = await getItem('token') + dispatch({ type: INITIALIZED, token }) + + // setup faye + FayeGitter.setAccessToken(token) + FayeGitter.create() + + // getting base current user's information + await dispatch(getCurrentUser()) + await Promise.all([ + dispatch(getRooms()), + dispatch(getSuggestedRooms()) + ]) + + // connect to the server and subscribe to rooms changes (Drawer) + await FayeGitter.connect() + dispatch(subscribeToRooms()) + dispatch(setupFayeEvents()) + } catch (error) { + dispatch({ type: INITIALIZED, error }) + } + } +} + + +function setupFayeEvents() { + return dispatch => { + // DeviceEventEmitter.addListener('FayeGitter:onDisconnected', + // DeviceEventEmitter.addListener('FayeGitter:onFailedToCreate', + DeviceEventEmitter.addListener('FayeGitter:Message', + event => dispatch(parseEvent(event)) + ) + // DeviceEventEmitter.addListener('FayeGitter:SubscribtionFailed', + // DeviceEventEmitter.addListener('FayeGitter:Subscribed', + // DeviceEventEmitter.addListener('FayeGitter:Unsubscribed', + DeviceEventEmitter.addListener('FayeGitter:log', log => console.log(log)) + } +} + +function parseEvent(event) { + return (dispatch, getState) => { + const json = JSON.parse(event.json) + const {id} = getState().viewer.user + const roomsChannel = `/api/v1/user/${id}/rooms` + + if (event.channel.match(roomsChannel)) { + dispatch(updateRoomState(json)) + } + } +} + +/** + * Reducer + */ + +const initialState = { + online: null, + appState: null +} + +export default function app(state = initialState, action) { + switch (action.type) { + case CHANGE_NET_STATUS: + return {...state, + online: action.payload + } + + case CHANGE_APP_STATE: + return {...state, + appState: action.payload + } + default: + return state + } +} diff --git a/app/modules/auth.js b/app/modules/auth.js index aea22b4..4845b40 100644 --- a/app/modules/auth.js +++ b/app/modules/auth.js @@ -1,4 +1,4 @@ -import {INITIALIZED} from './init' +import {INITIALIZED} from './app' import {setItem, removeItem} from '../utils/storage' import _ from 'lodash' import {getCurrentUser} from './viewer' diff --git a/app/modules/index.js b/app/modules/index.js index eab4b39..23213b9 100644 --- a/app/modules/index.js +++ b/app/modules/index.js @@ -1,10 +1,12 @@ import {combineReducers} from 'redux' +import app from './app' import auth from './auth' import rooms from './rooms' import viewer from './viewer' const rootReducer = combineReducers({ + app, auth, rooms, viewer diff --git a/app/modules/init.js b/app/modules/init.js deleted file mode 100644 index 2e06ea3..0000000 --- a/app/modules/init.js +++ /dev/null @@ -1,31 +0,0 @@ -import {getItem, removeItem} from '../utils/storage' -import {getCurrentUser} from './viewer' -import {getRooms, getSuggestedRooms} from './rooms' - -/** - * Constants - */ - -export const INITIALIZED = 'init/INITIALIZED' - - -/** - * Action Creators - */ - -export function init() { - return async (dispatch, getState) => { - try { - const token = await getItem('token') - dispatch({ type: INITIALIZED, token }) - - await dispatch(getCurrentUser()) - await Promise.all([ - dispatch(getRooms()), - dispatch(getSuggestedRooms()) - ]) - } catch (error) { - dispatch({ type: INITIALIZED, error }) - } - } -} diff --git a/app/modules/rooms.js b/app/modules/rooms.js index eb51bfb..50e1cb6 100644 --- a/app/modules/rooms.js +++ b/app/modules/rooms.js @@ -1,4 +1,6 @@ import * as Api from '../api/gitter' +import _ from 'lodash' +import FayeGitter from '../../libs/react-native-gitter-faye' import normalize from '../utils/normalize' import {LOGOUT} from './auth' @@ -14,6 +16,8 @@ export const SUGGESTED_ROOMS = 'rooms/SUGGESTED_ROOMS' export const SUGGESTED_ROOMS_RECEIVED = 'rooms/SUGGESTED_ROOMS_RECEIVED' export const SUGGESTED_ROOMS_FAILED = 'rooms/SUGGESTED_ROOMS_FAILED' export const SELECT_ROOM = 'rooms/SELECT_ROOM' +export const ROOMS_SUBSCRIBED = 'rooms/ROOMS_SUBSCRIBED' +export const UPDATE_ROOM_STATE = 'rooms/UPDATE_ROOM_STATE' /** @@ -62,6 +66,29 @@ export function selectRoom(roomId) { return {type: SELECT_ROOM, payload: roomId} } +/** + * Subscribe current user rooms changes (Drawer) + */ + +export function subscribeToRooms() { + return (dispatch, getState) => { + console.log('subscribeee') + const {id} = getState().viewer.user + FayeGitter.subscribe(`/api/v1/user/${id}/rooms`) + dispatch({type: ROOMS_SUBSCRIBED}) + } +} + +/** + * Update unread count by faye action + */ + +export function updateRoomState(json) { + return dispatch => { + dispatch({type: UPDATE_ROOM_STATE, payload: json}) + } +} + /** * Reducer */ @@ -107,8 +134,18 @@ export default function rooms(state = initialState, action) { } } + case UPDATE_ROOM_STATE: { + const {id} = action.payload.model + const room = state.rooms[id] + return {...state, + rooms: {...state.rooms, + [id]: _.merge(room, action.payload.model) + } + } + } + case LOGOUT: { - return Object.assign({}, initialState) + return initialState } case SUGGESTED_ROOMS_FAILED: From 87cabe922e1c1411151dc70932e32a6b70b16866 Mon Sep 17 00:00:00 2001 From: Terry Sahaidak Date: Thu, 25 Feb 2016 23:11:28 +0200 Subject: [PATCH 3/6] Redactor faye code --- app/modules/app.js | 46 ++++++++++++++++++++++++++++++-------------- app/modules/rooms.js | 1 - 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/app/modules/app.js b/app/modules/app.js index 5da026c..ad400f7 100644 --- a/app/modules/app.js +++ b/app/modules/app.js @@ -11,6 +11,7 @@ import {DeviceEventEmitter} from 'react-native' export const INITIALIZED = 'app/INITIALIZED' export const CHANGE_NET_STATUS = 'app/CHANGE_NET_STATUS' export const CHANGE_APP_STATE = 'app/CHANGE_APP_STATE' +export const FAYE_CONNECT = 'app/FAYE_CONNECT' /** * Action Creators @@ -22,10 +23,6 @@ export function init() { const token = await getItem('token') dispatch({ type: INITIALIZED, token }) - // setup faye - FayeGitter.setAccessToken(token) - FayeGitter.create() - // getting base current user's information await dispatch(getCurrentUser()) await Promise.all([ @@ -33,27 +30,41 @@ export function init() { dispatch(getSuggestedRooms()) ]) - // connect to the server and subscribe to rooms changes (Drawer) - await FayeGitter.connect() - dispatch(subscribeToRooms()) - dispatch(setupFayeEvents()) + // setup faye + await dispatch(setupFaye()) } catch (error) { dispatch({ type: INITIALIZED, error }) } } } +function setupFaye() { + return async (dispatch, getState) => { + FayeGitter.setAccessToken(getState().auth.token) + FayeGitter.create() + FayeGitter.logger() + dispatch(setupFayeEvents()) + try { + const result = await FayeGitter.connect() + dispatch({type: FAYE_CONNECT, payload: result}) + dispatch(subscribeToRooms()) + } catch (err) { + console.log(err) + } + } +} + function setupFayeEvents() { return dispatch => { - // DeviceEventEmitter.addListener('FayeGitter:onDisconnected', - // DeviceEventEmitter.addListener('FayeGitter:onFailedToCreate', + DeviceEventEmitter.addListener('FayeGitter:onDisconnected',log => console.log(log)) + DeviceEventEmitter.addListener('FayeGitter:onFailedToCreate',log => console.log(log)) DeviceEventEmitter.addListener('FayeGitter:Message', event => dispatch(parseEvent(event)) ) - // DeviceEventEmitter.addListener('FayeGitter:SubscribtionFailed', - // DeviceEventEmitter.addListener('FayeGitter:Subscribed', - // DeviceEventEmitter.addListener('FayeGitter:Unsubscribed', + DeviceEventEmitter.addListener('FayeGitter:SubscribtionFailed',log => console.log(log)) + DeviceEventEmitter.addListener('FayeGitter:Subscribed',log => console.log(log)) + DeviceEventEmitter.addListener('FayeGitter:Unsubscribed', log => console.log(log)) DeviceEventEmitter.addListener('FayeGitter:log', log => console.log(log)) } } @@ -76,7 +87,8 @@ function parseEvent(event) { const initialState = { online: null, - appState: null + appState: null, + fayeConnected: false } export default function app(state = initialState, action) { @@ -90,6 +102,12 @@ export default function app(state = initialState, action) { return {...state, appState: action.payload } + + case FAYE_CONNECT: + return {...state, + fayeConnected: action.payload + } + default: return state } diff --git a/app/modules/rooms.js b/app/modules/rooms.js index 50e1cb6..9063c55 100644 --- a/app/modules/rooms.js +++ b/app/modules/rooms.js @@ -72,7 +72,6 @@ export function selectRoom(roomId) { export function subscribeToRooms() { return (dispatch, getState) => { - console.log('subscribeee') const {id} = getState().viewer.user FayeGitter.subscribe(`/api/v1/user/${id}/rooms`) dispatch({type: ROOMS_SUBSCRIBED}) From 5b5498531c4e5d55a6bedb57ad6e2606e8e5f310 Mon Sep 17 00:00:00 2001 From: Terry Sahaidak Date: Sat, 27 Feb 2016 02:32:18 +0200 Subject: [PATCH 4/6] Add NetInfo, AppState and Faye with reconection --- android/app/src/main/AndroidManifest.xml | 1 + app/modules/app.js | 56 +++++++++++++++++++++--- app/modules/rooms.js | 1 + 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 7219191..6dbb2b2 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -2,6 +2,7 @@ package="com.gittermobile"> + { + dispatch(setupAppStatusListener()) + dispatch(setupFayeEvents()) try { const token = await getItem('token') - dispatch({ type: INITIALIZED, token }) + const netStatus = await NetInfo.fetch() + dispatch({ type: INITIALIZED, token, netStatus }) + + // TODO: do things belowe only if the internet is awailible (netStatus) // getting base current user's information await dispatch(getCurrentUser()) @@ -32,6 +37,7 @@ export function init() { // setup faye await dispatch(setupFaye()) + await dispatch(setupNetStatusListener()) } catch (error) { dispatch({ type: INITIALIZED, error }) } @@ -43,7 +49,6 @@ function setupFaye() { FayeGitter.setAccessToken(getState().auth.token) FayeGitter.create() FayeGitter.logger() - dispatch(setupFayeEvents()) try { const result = await FayeGitter.connect() dispatch({type: FAYE_CONNECT, payload: result}) @@ -57,8 +62,8 @@ function setupFaye() { function setupFayeEvents() { return dispatch => { - DeviceEventEmitter.addListener('FayeGitter:onDisconnected',log => console.log(log)) - DeviceEventEmitter.addListener('FayeGitter:onFailedToCreate',log => console.log(log)) + DeviceEventEmitter.addListener('FayeGitter:onDisconnected', log => dispatch(setupFaye())) + // DeviceEventEmitter.addListener('FayeGitter:onFailedToCreate', log => dispatch(setupFaye())) DeviceEventEmitter.addListener('FayeGitter:Message', event => dispatch(parseEvent(event)) ) @@ -71,16 +76,48 @@ function setupFayeEvents() { function parseEvent(event) { return (dispatch, getState) => { - const json = JSON.parse(event.json) + const message = JSON.parse(event.json) const {id} = getState().viewer.user const roomsChannel = `/api/v1/user/${id}/rooms` if (event.channel.match(roomsChannel)) { - dispatch(updateRoomState(json)) + dispatch(updateRoomState(message)) } } } +function onNetStatusChangeFaye(status) { + return async (dispatch, getState) => { + const {fayeConnected, online} = getState().app + if (!status && fayeConnected) { + dispatch({type: FAYE_CONNECT, payload: status}) + } + if (status && !fayeConnected) { + dispatch(setupFaye()) + } + } +} + +function setupNetStatusListener() { + return dispatch => { + NetInfo.isConnected.addEventListener('change', + async status => { + dispatch({type: CHANGE_NET_STATUS, payload: status}) + await dispatch(onNetStatusChangeFaye(status)) + } + ); + } +} + +function setupAppStatusListener() { + return dispatch => { + AppState.addEventListener('change', + status => dispatch({type: CHANGE_APP_STATE, payload: status}) + ); + } +} + + /** * Reducer */ @@ -93,6 +130,11 @@ const initialState = { export default function app(state = initialState, action) { switch (action.type) { + case INITIALIZED: + return {...state, + online: action.netStatus + } + case CHANGE_NET_STATUS: return {...state, online: action.payload diff --git a/app/modules/rooms.js b/app/modules/rooms.js index 9063c55..d471d04 100644 --- a/app/modules/rooms.js +++ b/app/modules/rooms.js @@ -17,6 +17,7 @@ export const SUGGESTED_ROOMS_RECEIVED = 'rooms/SUGGESTED_ROOMS_RECEIVED' export const SUGGESTED_ROOMS_FAILED = 'rooms/SUGGESTED_ROOMS_FAILED' export const SELECT_ROOM = 'rooms/SELECT_ROOM' export const ROOMS_SUBSCRIBED = 'rooms/ROOMS_SUBSCRIBED' +export const ROOMS_UNSUBSCRIBED = 'rooms/ROOMS_UNSUBSCRIBED' export const UPDATE_ROOM_STATE = 'rooms/UPDATE_ROOM_STATE' From 48407f171aa2d3fb4ecb9c9c05f2a21e92b73159 Mon Sep 17 00:00:00 2001 From: Terry Sahaidak Date: Sat, 27 Feb 2016 02:44:14 +0200 Subject: [PATCH 5/6] fix bug with lurk badge --- app/components/ChannelListItem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/components/ChannelListItem.js b/app/components/ChannelListItem.js index 9129511..050a832 100644 --- a/app/components/ChannelListItem.js +++ b/app/components/ChannelListItem.js @@ -36,7 +36,7 @@ const ChannelListItem = ({id, name, oneToOne, user, activeRoom, onRoomPress, unr {name} - {(!!unreadItems || !!mentions || !!lurk) && + {(!!unreadItems || !!mentions || !!lurk && !!unreadItems) && Date: Sat, 27 Feb 2016 21:10:22 +0200 Subject: [PATCH 6/6] fix some bugs, add reconnecttion if filed --- app/components/ChannelListItem.js | 2 +- app/modules/app.js | 74 +++++++++++++++++++------------ 2 files changed, 46 insertions(+), 30 deletions(-) diff --git a/app/components/ChannelListItem.js b/app/components/ChannelListItem.js index 050a832..9129511 100644 --- a/app/components/ChannelListItem.js +++ b/app/components/ChannelListItem.js @@ -36,7 +36,7 @@ const ChannelListItem = ({id, name, oneToOne, user, activeRoom, onRoomPress, unr {name} - {(!!unreadItems || !!mentions || !!lurk && !!unreadItems) && + {(!!unreadItems || !!mentions || !!lurk) && { - DeviceEventEmitter.addListener('FayeGitter:onDisconnected', log => dispatch(setupFaye())) - // DeviceEventEmitter.addListener('FayeGitter:onFailedToCreate', log => dispatch(setupFaye())) - DeviceEventEmitter.addListener('FayeGitter:Message', - event => dispatch(parseEvent(event)) - ) - DeviceEventEmitter.addListener('FayeGitter:SubscribtionFailed',log => console.log(log)) - DeviceEventEmitter.addListener('FayeGitter:Subscribed',log => console.log(log)) - DeviceEventEmitter.addListener('FayeGitter:Unsubscribed', log => console.log(log)) - DeviceEventEmitter.addListener('FayeGitter:log', log => console.log(log)) - } -} - -function parseEvent(event) { - return (dispatch, getState) => { - const message = JSON.parse(event.json) - const {id} = getState().viewer.user - const roomsChannel = `/api/v1/user/${id}/rooms` - - if (event.channel.match(roomsChannel)) { - dispatch(updateRoomState(message)) + console.log(err) // eslint-disable-line no-console } } } function onNetStatusChangeFaye(status) { return async (dispatch, getState) => { - const {fayeConnected, online} = getState().app + const {fayeConnected} = getState().app if (!status && fayeConnected) { dispatch({type: FAYE_CONNECT, payload: status}) } @@ -118,6 +91,49 @@ function setupAppStatusListener() { } +function setupFayeEvents() { + return (dispatch, getState) => { + DeviceEventEmitter + .addListener('FayeGitter:onDisconnected', log => { + console.warn(log) // eslint-disable-line no-console + dispatch(setupFaye()) + }) + + DeviceEventEmitter + .addListener('FayeGitter:onFailedToCreate', log => { + console.warn(log) // eslint-disable-line no-console + if (getState().app.netStatus) { + dispatch(setupFaye()) + } + }) + DeviceEventEmitter + .addListener('FayeGitter:Message', event => { + dispatch(parseEvent(event)) + }) + DeviceEventEmitter + .addListener('FayeGitter:SubscribtionFailed', log => console.warn(log)) // eslint-disable-line no-console + DeviceEventEmitter + .addListener('FayeGitter:Subscribed', log => console.log(log)) // eslint-disable-line no-console + DeviceEventEmitter + .addListener('FayeGitter:Unsubscribed', log => console.log(log)) // eslint-disable-line no-console + DeviceEventEmitter + .addListener('FayeGitter:log', log => console.log(log)) // eslint-disable-line no-console + } +} + +function parseEvent(event) { + return (dispatch, getState) => { + const message = JSON.parse(event.json) + const {id} = getState().viewer.user + const roomsChannel = `/api/v1/user/${id}/rooms` + + if (event.channel.match(roomsChannel)) { + dispatch(updateRoomState(message)) + } + } +} + + /** * Reducer */