diff --git a/app/actions/actionsTypes.js b/app/actions/actionsTypes.js index 5d07a3201..07ca9a4c2 100644 --- a/app/actions/actionsTypes.js +++ b/app/actions/actionsTypes.js @@ -10,9 +10,10 @@ function createRequestTypes(base, types = defaultTypes) { } // Login events -export const LOGIN = createRequestTypes('LOGIN'); +export const LOGIN = createRequestTypes('LOGIN', [...defaultTypes, 'SET_TOKEN']); export const ROOMS = createRequestTypes('ROOMS'); export const MESSAGES = createRequestTypes('MESSAGES'); +export const SERVER = createRequestTypes('SERVER', ['SELECT', 'CHANGED']); export const METEOR = createRequestTypes('METEOR_CONNECT', [...defaultTypes, 'DISCONNECT']); export const LOGOUT = 'LOGOUT'; // logout is always success diff --git a/app/actions/login.js b/app/actions/login.js index 90cd937c0..4f8c248d8 100644 --- a/app/actions/login.js +++ b/app/actions/login.js @@ -10,7 +10,8 @@ export function loginRequest(credentials) { export function loginSuccess(user) { return { type: types.LOGIN.SUCCESS, - user + user, + token: user.token }; } @@ -21,8 +22,14 @@ export function loginFailure(err) { }; } +export function setToken(token) { + return { + type: types.LOGIN.SET_TOKEN, + token + }; +} + export function logout() { - console.log('LOGOUT'); return { type: types.LOGOUT }; diff --git a/app/actions/server.js b/app/actions/server.js new file mode 100644 index 000000000..230b4cd06 --- /dev/null +++ b/app/actions/server.js @@ -0,0 +1,14 @@ +import { SERVER } from './actionsTypes'; + +export function setServer(server) { + return { + type: SERVER.SELECT, + server + }; +} +export function changedServer(server) { + return { + type: SERVER.CHANGED, + server + }; +} diff --git a/app/components/RoomItem.js b/app/components/RoomItem.js index baa4062d1..b93f4cfbe 100644 --- a/app/components/RoomItem.js +++ b/app/components/RoomItem.js @@ -2,7 +2,7 @@ import React from 'react'; import { CachedImage } from 'react-native-img-cache'; import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'; import PropTypes from 'prop-types'; -import { View, Text, StyleSheet } from 'react-native'; +import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'; import avatarInitialsAndColor from '../utils/avatarInitialsAndColor'; @@ -106,16 +106,17 @@ export default class RoomItem extends React.PureComponent { } render() { + const { item } = this.props; let extraSpace = {}; - if (this.props.item.unread) { + if (item.unread) { extraSpace = { paddingRight: 92 }; } return ( - + this.props.onPress(item._id, item)} style={[styles.container, extraSpace]}> {this.icon} { this.props.item.name } {this.renderNumber(this.props.item)} - + ); } } diff --git a/app/components/banner.js b/app/components/banner.js index 181d65954..77a03a1e1 100644 --- a/app/components/banner.js +++ b/app/components/banner.js @@ -14,8 +14,8 @@ const styles = StyleSheet.create({ }); @connect(state => ({ - connecting: state.meteor && state.meteor.connecting, - authenticating: state.login && state.login.isFetching, + connecting: state.meteor.connecting, + authenticating: state.login.isFetching, offline: !state.meteor.connected })) diff --git a/app/components/message/card.js b/app/components/message/card.js index b97cd8e57..23adb43d0 100644 --- a/app/components/message/card.js +++ b/app/components/message/card.js @@ -1,6 +1,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import Meteor from 'react-native-meteor'; +import { connect } from 'react-redux'; import { CachedImage } from 'react-native-img-cache'; import { Text, TouchableOpacity } from 'react-native'; import { Navigation } from 'react-native-navigation'; @@ -24,6 +25,11 @@ const CustomButton = ({ text }) => ( ); Navigation.registerComponent('CustomButton', () => CustomButton); +@connect(state => ({ + base: state.settings.Site_Url, + canShowList: state.login.token.length || state.login.user.token +})) + export default class Cards extends React.PureComponent { static propTypes = { data: PropTypes.object.isRequired @@ -33,7 +39,7 @@ export default class Cards extends React.PureComponent { const user = Meteor.user(); this.state = {}; RocketChat.getUserToken().then((token) => { - this.setState({ img: `${ RocketChat.currentServer }${ this.props.data.image_url }?rc_uid=${ user._id }&rc_token=${ token }` }); + this.setState({ img: `${ this.props.base }${ this.props.data.image_url }?rc_uid=${ user._id }&rc_token=${ token }` }); }); } _onPressButton() { diff --git a/app/lib/createStore.js b/app/lib/createStore.js index 749e2860a..7e6599e5b 100644 --- a/app/lib/createStore.js +++ b/app/lib/createStore.js @@ -20,6 +20,6 @@ if (__DEV__) { export default createStore( reducers, - applyMiddleware(sagaMiddleware) + applyMiddleware(...middleware) ); sagaMiddleware.run(sagas); diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index 42def78f5..900cc6a6a 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -9,7 +9,7 @@ import settingsType from '../constants/settings'; import realm from './realm'; import * as actions from '../actions'; import { disconnect, connectSuccess } from '../actions/connect'; -import { logout, loginSuccess } from '../actions/login'; +import { loginSuccess } from '../actions/login'; export { Accounts } from 'react-native-meteor'; @@ -29,18 +29,6 @@ const RocketChat = { }); }, - get currentServer() { - const current = realm.objects('servers').filtered('current = true').slice(0, 1)[0]; - return current && current.id; - }, - - set currentServer(server) { - realm.write(() => { - realm.objects('servers').filtered('current = true').forEach(item => (item.current = false)); - realm.create('servers', { id: server, current: true }, true); - }); - }, - async getUserToken() { const TOKEN_KEY = 'reactnativemeteor_usertoken'; try { @@ -50,23 +38,20 @@ const RocketChat = { } }, - connect(cb) { - return new Promise((resolve, reject) => { - const url = `${ RocketChat.currentServer }/websocket`; + connect(_url) { + return new Promise((resolve) => { + const url = `${ _url }/websocket`; Meteor.connect(url, { autoConnect: true, autoReconnect: true }); // , { autoConnect: false, autoReconnect: false } Meteor.ddp.on('disconnected', () => { - console.log('disconnected'); reduxStore.dispatch(disconnect()); }); - Meteor.ddp.on('connected', (err) => { - console.log('connected'); + Meteor.ddp.on('connected', () => { reduxStore.dispatch(connectSuccess()); resolve(); }); Meteor.ddp.on('loggin', () => { - console.log('Meteor.ddp.on(\'loggin\','); reduxStore.dispatch(loginSuccess({})); }); Meteor.ddp.on('connected', () => { @@ -81,7 +66,7 @@ const RocketChat = { const setting = { _id: item._id }; - setting._server = { id: RocketChat.currentServer }; + setting._server = { id: reduxStore.getState().server }; if (settingsType[item.type]) { setting[settingsType[item.type]] = item.value; realm.create('settings', setting, true); @@ -91,10 +76,6 @@ const RocketChat = { }); }); reduxStore.dispatch(actions.setAllSettings(settings)); - - if (typeof cb === 'function') { - cb(); - } }); Meteor.ddp.on('changed', (ddbMessage) => { @@ -103,7 +84,7 @@ const RocketChat = { realm.write(() => { const message = ddbMessage.fields.args[0]; message.temp = false; - message._server = { id: RocketChat.currentServer }; + message._server = { id: reduxStore.getState().server }; // write('messages', message); realm.create('messages', message, true); }); @@ -113,24 +94,27 @@ const RocketChat = { // console.log(ddbMessage); realm.write(() => { const data = ddbMessage.fields.args[1]; - data._server = { id: RocketChat.currentServer }; + data._server = { id: reduxStore.getState().server }; realm.create('subscriptions', data, true); }); } }); }); - }); + }) + .catch(e => console.error(e)); }, login(params, callback) { return new Promise((resolve, reject) => { Meteor._startLoggingIn(); - console.log('meteor login', params); return Meteor.call('login', params, (err, result) => { Meteor._endLoggingIn(); Meteor._handleLoginCallback(err, result); - console.log(result); - err ? reject(err) : resolve(result); + if (err) { + reject(err); + } else { + resolve(result); + } if (typeof callback === 'function') { callback(err, result); } @@ -194,7 +178,7 @@ const RocketChat = { // if (typeof item.value === 'string') { // subscription.value = item.value; // } - subscription._server = { id: RocketChat.currentServer }; + subscription._server = { id: reduxStore.getState().server }; // write('subscriptions', subscription); realm.create('subscriptions', subscription, true); }); @@ -218,7 +202,7 @@ const RocketChat = { realm.write(() => { data.messages.forEach((message) => { message.temp = false; - message._server = { id: RocketChat.currentServer }; + message._server = { id: reduxStore.getState().server }; // write('messages', message); realm.create('messages', message, true); }); @@ -240,7 +224,6 @@ const RocketChat = { getMessage(rid, msg = {}) { const _id = Random.id(); - const user = Meteor.user(); const message = { _id, rid, @@ -248,10 +231,10 @@ const RocketChat = { ts: new Date(), _updatedAt: new Date(), temp: true, - _server: { id: RocketChat.currentServer }, + _server: { id: reduxStore.getState().server }, u: { - _id: user._id, - username: user.username + _id: reduxStore.getState()._id, + username: reduxStore.getState()._id } }; @@ -400,16 +383,13 @@ const RocketChat = { // if (typeof item.value === 'string') { // subscription.value = item.value; // } - subscription._server = { id: RocketChat.currentServer }; + subscription._server = { id: reduxStore.getState().server }; // write('subscriptions', subscription); realm.create('subscriptions', subscription, true); }); }); return data; - }).then((data) => { - console.log('subscriptions done.'); - return data; - }); + }).then(data => data); // }); }, logout() { @@ -418,9 +398,3 @@ const RocketChat = { }; export default RocketChat; - -if (RocketChat.currentServer) { - reduxStore.dispatch(actions.setCurrentServer(RocketChat.currentServer)); -} -// Use for logout -// AsyncStorage.clear(); diff --git a/app/navigation.js b/app/navigation.js index 513a2cb9a..65a87c97e 100644 --- a/app/navigation.js +++ b/app/navigation.js @@ -20,8 +20,8 @@ Navigation.registerComponent('CreateChannel', () => CreateChannel, store, Provid Navigation.startSingleScreenApp({ screen: { - screen: 'Rooms', - title: 'Channels' + screen: 'ListServer', + title: 'ListServer' }, animationType: 'none' }); diff --git a/app/reducers/index.js b/app/reducers/index.js index 2bc2642d8..bc162c812 100644 --- a/app/reducers/index.js +++ b/app/reducers/index.js @@ -3,10 +3,9 @@ import * as reducers from './reducers'; import login from './login'; import meteor from './connect'; import messages from './messages'; +import server from './server'; + -console.log(Object.keys({ - ...reducers, login, meteor, messages -})); export default combineReducers({ - ...reducers, login, meteor, messages + ...reducers, login, meteor, messages, server }); diff --git a/app/reducers/login.js b/app/reducers/login.js index 3ed4e74d6..4aacbd590 100644 --- a/app/reducers/login.js +++ b/app/reducers/login.js @@ -32,11 +32,14 @@ export default function login(state = initialState, action) { errorMessage: action.err }; case types.LOGOUT: - console.log('LOGOUT'); return { ...state, isFetching: false, isAuthenticated: false }; + case types.LOGIN.SET_TOKEN: + return { ...state, + token: action.token + }; default: return state; } diff --git a/app/reducers/reducers.js b/app/reducers/reducers.js index 7e23459fc..561e609bb 100644 --- a/app/reducers/reducers.js +++ b/app/reducers/reducers.js @@ -1,17 +1,7 @@ -import RocketChat from '../lib/rocketchat'; import * as types from '../constants/types'; import initialState from './initialState'; -export function server(state = initialState.server, action) { - if (action.type === types.SET_CURRENT_SERVER) { - RocketChat.currentServer = action.payload; - return action.payload; - } - - return state; -} - -export function settings(state = initialState.settings, action) { +export default function settings(state = initialState.settings, action) { if (action.type === types.SET_ALL_SETTINGS) { return { ...state, ...action.payload diff --git a/app/reducers/server.js b/app/reducers/server.js new file mode 100644 index 000000000..8ee296cd5 --- /dev/null +++ b/app/reducers/server.js @@ -0,0 +1,10 @@ +import { SERVER } from '../actions/actionsTypes'; + +export default function server(state = '', action) { + switch (action.type) { + case SERVER.SELECT: + return action.server; + default: + return state; + } +} diff --git a/app/sagas/connect.js b/app/sagas/connect.js index 20b5b5a7e..4a8ac45f3 100644 --- a/app/sagas/connect.js +++ b/app/sagas/connect.js @@ -1,33 +1,26 @@ -import { take, put, call, fork, takeLatest } from 'redux-saga/effects'; +import { take, put, call, fork, takeLatest, select } from 'redux-saga/effects'; import { METEOR } from '../actions/actionsTypes'; import RocketChat from '../lib/rocketchat'; -import { connectSuccess, connectRequest, connectFailure } from '../actions/connect'; +import { connectSuccess, connectFailure } from '../actions/connect'; -function connect(...args) { - return RocketChat.connect(...args); -} -const auto = function* auto() { - while (true) { - yield take(METEOR.DISCONNECT); - console.log('\n\n[METEOR DISCONNECT]\n\n'); - yield put(connectRequest()); +const getServer = ({ server }) => server; + + +const connect = url => RocketChat.connect(url); +const test = function* test() { + try { + const server = yield select(getServer); + const response = yield call(connect, server); + yield put(connectSuccess(response)); + } catch (err) { + yield put(connectFailure(err.status)); } }; -const test = function* test() { - const response = yield call(connect); - yield put(connectSuccess(response)); - console.log('\n\n[METEOR CONNECTED]\n\n'); -}; const watchConnect = function* watchConnect() { + yield takeLatest(METEOR.REQUEST, test); while (true) { - try { - yield takeLatest(METEOR.REQUEST, test); - } catch (err) { - yield put(connectFailure(err.status)); - } yield take(METEOR.DISCONNECT); - console.log('\n\n[METEOR DISCONNECT]\n\n'); } }; const root = function* root() { diff --git a/app/sagas/index.js b/app/sagas/index.js index 9b9e0f2de..8bc3d026a 100644 --- a/app/sagas/index.js +++ b/app/sagas/index.js @@ -3,16 +3,16 @@ import hello from './hello'; import login from './login'; import connect from './connect'; import rooms from './rooms'; -import logger from './logger'; import messages from './messages'; +import selectServer from './selectServer'; const root = function* root() { yield fork(hello); yield fork(rooms); yield fork(login); yield fork(connect); - yield fork(logger); yield fork(messages); + yield fork(selectServer); }; // Consider using takeEvery export default root; diff --git a/app/sagas/logger.js b/app/sagas/logger.js deleted file mode 100644 index a8c5f485e..000000000 --- a/app/sagas/logger.js +++ /dev/null @@ -1,12 +0,0 @@ -import { select, takeEvery } from 'redux-saga/effects'; - -const root = function* watchAndLog() { - // yield takeEvery('*', function* logger(action) { - // const state = yield select(); - // const tmp = { ...state }; - // delete tmp.settings; - // console.log('action', action); - // console.log('state after', tmp); - // }); -}; -export default root; diff --git a/app/sagas/login.js b/app/sagas/login.js index 62555fd3b..6462ff71d 100644 --- a/app/sagas/login.js +++ b/app/sagas/login.js @@ -1,48 +1,55 @@ -import React from 'react'; -import { take, put, call, takeLast, fork, select } from 'redux-saga/effects'; +import { AsyncStorage } from 'react-native'; +import { take, put, call, takeEvery, fork, select, all } from 'redux-saga/effects'; import * as types from '../actions/actionsTypes'; -import { loginRequest, loginSuccess, loginFailure, logout } from '../actions/login'; +import { loginRequest, loginSuccess, loginFailure, setToken } from '../actions/login'; import RocketChat from '../lib/rocketchat'; +const TOKEN_KEY = 'reactnativemeteor_usertoken'; const getUser = state => state.login.user; -function loginCall(args) { - return args.resume ? RocketChat.login(args) : RocketChat.loginWithPassword(args); -} -const auto = function* auto() { - while (true) { - yield take(types.LOGOUT); - yield take(types.METEOR.SUCCESS); - const user = yield select(getUser); - if (user.token) { - yield put(loginRequest({ resume: user.token })); - } +const getServer = state => state.server; +const loginCall = args => (args.resume ? RocketChat.login(args) : RocketChat.loginWithPassword(args)); + +const getToken = function* getToken() { + const currentServer = yield select(getServer); + console.log('currentServer', currentServer); + const token = yield call([AsyncStorage, 'getItem'], `${ TOKEN_KEY }-${ currentServer }`); + console.log('currentServer TOKEN', token); + if (token) { yield put(setToken(token)); } + // yield call([AsyncStorage, 'setItem'], TOKEN_KEY, token || ''); + return token; +}; + +const sagaLogin = function* sagaLogin(payload) { + try { + const response = yield call(loginCall, payload); + yield put(loginSuccess(response)); + } catch (err) { + yield put(loginFailure(err)); } }; const watchLoginRequest = function* watchLoginRequest() { - while (true) { + do { try { - yield take(types.METEOR.SUCCESS); - // console.log('\n\n[LOGIN METEOR CONNECTED]\n\n'); - const payload = yield take(types.LOGIN.REQUEST); - try { - const response = yield call(loginCall, payload); - yield put(loginSuccess(response)); - console.log('\n\n[LOGIN SUCCESS]\n\n'); - } catch (err) { - // console.log('\n\n[LOGIN FAILURE]\n\n', err); - yield put(loginFailure(err.status)); + yield all([take(types.METEOR.SUCCESS), take(types.SERVER.CHANGED)]); + const token = yield call(getToken); + if (token) { + yield put(loginRequest({ resume: token })); } - yield take(types.METEOR.DISCONNECT); - console.log('\n\n[METEOR DISCONNECT LOGOUT]\n\n'); - yield put(logout()); } catch (e) { - console.error(e); + console.log(e); } - } + } while (true); +}; + +const saveToken = function* saveToken() { + const [server, user] = yield all([select(getServer), select(getUser)]); + yield AsyncStorage.setItem(TOKEN_KEY, user.token); + yield AsyncStorage.setItem(`${ TOKEN_KEY }-${ server }`, user.token); }; const root = function* root() { yield fork(watchLoginRequest); - yield fork(auto); + yield takeEvery(types.LOGIN.REQUEST, sagaLogin); + yield takeEvery(types.LOGIN.SUCCESS, saveToken); }; export default root; diff --git a/app/sagas/rooms.js b/app/sagas/rooms.js index 1c8dfeb9b..9cf6c7b94 100644 --- a/app/sagas/rooms.js +++ b/app/sagas/rooms.js @@ -1,28 +1,21 @@ -import { take, put, call, fork } from 'redux-saga/effects'; +import { put, call, takeEvery } from 'redux-saga/effects'; import * as types from '../actions/actionsTypes'; import { roomsSuccess, roomsFailure } from '../actions/rooms'; import RocketChat from '../lib/rocketchat'; -function getRooms(...args) { - // console.log('\n\n\n\n\n\naqui\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n'); - return RocketChat.getRooms(...args); -} - -const watchRoomsRequest = function* watchRoomsRequest() { - // console.log('\n\n\n\n\n\n\n\nWAINTING FOR LOGINsss\n\n\n\n\n\n\n\n'); - while (true) { - // console.log('\n\n\n\n\n\n\n\nWAINTING FOR LOGIN\n\n\n\n\n\n\n\n'); - yield take(types.LOGIN.SUCCESS); - // console.log('\n\n\n\n\n\n\n\nWAINTING FOR LOGIN NO MORE\n\n\n\n\n\n\n\n'); - // const payload = yield take(types.ROOMS.REQUEST); - try { - yield call(getRooms); - yield put(roomsSuccess()); - } catch (err) { - console.log(err); - yield put(roomsFailure(err.status)); - } - } +const getRooms = function* getRooms() { + return yield RocketChat.getRooms(); }; -export default watchRoomsRequest; +const watchRoomsRequest = function* watchRoomsRequest() { + try { + yield call(getRooms); + yield put(roomsSuccess()); + } catch (err) { + yield put(roomsFailure(err.status)); + } +}; +const root = function* root() { + yield takeEvery(types.LOGIN.SUCCESS, watchRoomsRequest); +}; +export default root; diff --git a/app/sagas/selectServer.js b/app/sagas/selectServer.js new file mode 100644 index 000000000..2e81c25bf --- /dev/null +++ b/app/sagas/selectServer.js @@ -0,0 +1,21 @@ +import { put, takeEvery } from 'redux-saga/effects'; + +import { SERVER } from '../actions/actionsTypes'; +import { connectRequest, disconnect } from '../actions/connect'; +import { changedServer } from '../actions/server'; + +const selectServer = function* selectServer(server) { + try { + yield put(disconnect()); + yield put(changedServer(server)); + yield (server && put(connectRequest(server))); + // console.log(Actions.login()); + // Actions.replace('login', {}); + } catch (e) { + console.log(e); + } +}; +const root = function* root() { + yield takeEvery(SERVER.SELECT, selectServer); +}; +export default root; diff --git a/app/views/login.js b/app/views/login.js index 3b60024b0..48c71e660 100644 --- a/app/views/login.js +++ b/app/views/login.js @@ -68,27 +68,6 @@ class LoginView extends React.Component { console.log({ username, password, code }); this.props.loginRequest({ username, password, code }); this.props.navigator.dismissModal(); - // - // - // this.setState({ - // error: undefined - // }); - // - // - // RocketChat.loginWithPassword(credentials, (error) => { - // if (error) { - // if (error.error === 'totp-required') { - // this.setState({ totp: true }); - // this.codeInput.focus(); - // } else { - // this.setState({ - // error: error.reason - // }); - // } - // } else { - // this.props.navigator.dismissModal(); - // } - // }); } renderTOTP = () => { @@ -147,7 +126,7 @@ function mapStateToProps(state) { server: state.server, Accounts_EmailOrUsernamePlaceholder: state.settings.Accounts_EmailOrUsernamePlaceholder, Accounts_PasswordPlaceholder: state.settings.Accounts_PasswordPlaceholder, - login: state.login || state.default + login: state.login }; } diff --git a/app/views/roomsList.js b/app/views/roomsList.js index 61b2c2915..fc89ea941 100644 --- a/app/views/roomsList.js +++ b/app/views/roomsList.js @@ -1,20 +1,16 @@ import ActionButton from 'react-native-action-button'; -import { Navigation } from 'react-native-navigation'; +// import { Navigation } from 'react-native-navigation'; import { ListView } from 'realm/react-native'; -import Icon from 'react-native-vector-icons/Ionicons'; import React from 'react'; import PropTypes from 'prop-types'; -import { Text, View, StyleSheet, TouchableOpacity, Platform, TextInput } from 'react-native'; -import Meteor from 'react-native-meteor'; -import { bindActionCreators } from 'redux'; +import { View, StyleSheet, TextInput } from 'react-native'; import { connect } from 'react-redux'; import * as actions from '../actions'; -import * as meteor from '../actions/connect'; +import * as server from '../actions/connect'; import realm from '../lib/realm'; import RocketChat from '../lib/rocketchat'; import RoomItem from '../components/RoomItem'; import Banner from '../components/banner'; -// import debounce from '../utils/debounce'; const styles = StyleSheet.create({ container: { @@ -58,106 +54,37 @@ const styles = StyleSheet.create({ }); const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); -class RoomsListItem extends React.PureComponent { - static propTypes = { - item: PropTypes.object.isRequired, - onPress: PropTypes.func.isRequired, - baseUrl: PropTypes.string - } - _onPress = (...args) => { - this.props.onPress(...args); - }; - - render() { - const { item } = this.props; - return ( - this.props.onPress(item._id, item)}> - - - ); - } -} @connect(state => ({ server: state.server, - Site_Url: state.settings.Site_Url + login: state.login, + Site_Url: state.settings.Site_Url, + canShowList: state.login.token.length || state.login.user.token }), dispatch => ({ - actions: bindActionCreators(actions, dispatch), login: () => dispatch(actions.login()), - connect: () => dispatch(meteor.connectRequest()) + connect: () => dispatch(server.connectRequest()) })) export default class RoomsListView extends React.Component { static propTypes = { - navigator: PropTypes.object.isRequired, - server: PropTypes.string, - Site_Url: PropTypes.string + // navigator: PropTypes.object.isRequired, + server: PropTypes.string } constructor(props) { super(props); - - // this.data = realm.objects('subscriptions').filtered('_server.id = $0', this.props.server); + this.data = realm.objects('subscriptions').filtered('_server.id = $0', this.props.server); this.state = { - dataSource: ds.cloneWithRows([]), + dataSource: ds.cloneWithRows(this.data), searching: false, searchDataSource: [], - searchText: '' + searchText: '', + login: false }; - - this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this)); - } - - componentWillMount() { - const button = Platform.OS === 'ios' ? 'leftButtons' : 'rightButtons'; - this.props.navigator.setButtons({ - [button]: [{ - id: 'servers', - title: 'Servers' - }], - animated: true - }); - - if (this.props.server) { - this.setInitialData(); - } else { - Navigation.showModal({ - screen: 'ListServer', - passProps: {}, - navigatorStyle: {}, - navigatorButtons: {}, - animationType: 'none' - }); - } - } - - componentWillReceiveProps(nextProps) { - if (nextProps.server !== this.props.server) { - this.setInitialData(nextProps); - } } componentWillUnmount() { - this.state.data.removeListener(this.updateState); - } - - onNavigatorEvent = (event) => { - if (event.type === 'NavBarButtonPress') { - if (event.id === 'servers') { - Navigation.showModal({ - screen: 'ListServer', - passProps: {}, - navigatorStyle: {}, - navigatorButtons: {}, - animationType: 'slide-up' - // animationType: 'none' - }); - } - } + this.data.removeListener(this.updateState); } onSearchChangeText = (text) => { @@ -168,11 +95,11 @@ export default class RoomsListView extends React.Component { }); if (searchText === '') { return this.setState({ - dataSource: ds.cloneWithRows(this.state.data) + dataSource: ds.cloneWithRows(this.data) }); } - const data = this.state.data.filtered('name CONTAINS[c] $0', searchText).slice(); + const data = this.data.filtered('name CONTAINS[c] $0', searchText).slice(); const usernames = []; const dataSource = data.map((sub) => { @@ -218,31 +145,6 @@ export default class RoomsListView extends React.Component { }); } - setInitialData = (props = this.props) => { - // console.log(this.props); - this.props.connect(); - props.navigator.setSubTitle({ - subtitle: props.server - }); - RocketChat.getUserToken().then((token) => { - if (!token) { - Navigation.showModal({ - screen: 'Login', - animationType: 'slide-up' - }); - } - - - const data = realm.objects('subscriptions').filtered('_server.id = $0', props.server).sorted('_updatedAt', true); - - this.setState({ - dataSource: ds.cloneWithRows(data), - data - }); - - data.addListener(this.updateState); - }); - } updateState = () => { this.setState({ @@ -252,10 +154,10 @@ export default class RoomsListView extends React.Component { _onPressItem = (id, item = {}) => { const navigateToRoom = (room) => { - this.props.navigator.push({ - screen: 'Room', - passProps: room - }); + // this.props.navigator.push({ + // screen: 'Room', + // passProps: room + // }); }; const clearSearch = () => { @@ -297,26 +199,10 @@ export default class RoomsListView extends React.Component { clearSearch(); } - _createChannel = () => { - this.props.navigator.showModal({ - screen: 'CreateChannel' - }); - } - renderItem = ({ item }) => ( - this._onPressItem(item._id, item)} - baseUrl={this.props.Site_Url} - /> - ); - - renderSeparator = () => ( - - ); - renderSearchBar = () => ( ); - // if (!this.state.searching && !this.state.dataSource.length) { - // return ( - // - // No rooms - // - // ); - // } + renderItem = item => ( + this._onPressItem(item._id, item)} + /> + ) renderList = () => ( - // data={this.state.searching ? this.state.searchDataSource : this.state.dataSource} - // keyExtractor={item => item._id} - // ItemSeparatorComponent={this.renderSeparator} - // renderItem={this.renderItem} this.renderItem({ item })} + renderRow={this.renderItem} renderHeader={this.renderSearchBar} contentOffset={{ x: 0, y: 20 }} enableEmptySections keyboardShouldPersistTaps='always' /> ) - - renderCreateButtons() { - return ( - - { this.props.login(); }} > - - - ); - } - render() { - return ( - - - {this.renderList()} - {this.renderCreateButtons()} - - ); + renderCreateButtons = () => ( + ); + render= () => { + if (this.props.canShowList) { + return ( + + + {this.renderList()} + {this.renderCreateButtons()} + ); + } + return null; } } diff --git a/app/views/serverList.js b/app/views/serverList.js index b572a93c9..ab7156cb0 100644 --- a/app/views/serverList.js +++ b/app/views/serverList.js @@ -1,14 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Navigation } from 'react-native-navigation'; -import { bindActionCreators } from 'redux'; import Zeroconf from 'react-native-zeroconf'; import { View, Text, SectionList, Platform, StyleSheet } from 'react-native'; import { connect } from 'react-redux'; - -import * as actions from '../actions'; +import { setServer } from '../actions/server'; import realm from '../lib/realm'; -import RocketChat from '../lib/rocketchat'; const styles = StyleSheet.create({ view: { @@ -56,7 +53,7 @@ const zeroconf = new Zeroconf(); @connect(state => ({ server: state.server }), dispatch => ({ - actions: bindActionCreators(actions, dispatch) + selectServer: server => dispatch(setServer(server)) })) export default class ListServerView extends React.Component { static propTypes = { @@ -131,14 +128,7 @@ export default class ListServerView extends React.Component { } onPressItem = (item) => { - RocketChat.logout(); - Navigation.dismissModal({ - animationType: 'slide-down' - }); - - this.setState({ - server: item.id - }); + this.props.selectServer(item.id); } getState = () => { @@ -177,7 +167,7 @@ export default class ListServerView extends React.Component { renderItem = ({ item }) => ( { this.onPressItem(item); }} > {item.id}