Init Redux usage
This commit is contained in:
parent
2626e4a7bb
commit
37d34b0b1f
3
.babelrc
3
.babelrc
|
@ -1,3 +1,4 @@
|
||||||
{
|
{
|
||||||
"presets": ["react-native"]
|
"presets": ["react-native"],
|
||||||
|
"plugins": ["transform-decorators-legacy"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,5 +115,7 @@
|
||||||
"object-shorthand": 2,
|
"object-shorthand": 2,
|
||||||
"consistent-return": 0
|
"consistent-return": 0
|
||||||
},
|
},
|
||||||
"globals": {}
|
"globals": {
|
||||||
|
"__DEV__": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
import * as types from '../constants/types';
|
||||||
|
|
||||||
|
export function setCurrentServer(server) {
|
||||||
|
return {
|
||||||
|
type: types.SET_CURRENT_SERVER,
|
||||||
|
payload: server
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function preventESLintError() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
// // GENRES
|
||||||
|
// export function retrieveMoviesGenresSuccess(res) {
|
||||||
|
// return {
|
||||||
|
// type: types.RETRIEVE_MOVIES_GENRES_SUCCESS,
|
||||||
|
// moviesGenres: res.data
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export function retrieveMoviesGenres() {
|
||||||
|
// return function (dispatch) {
|
||||||
|
// return axios.get(`${TMDB_URL}/genre/movie/list?api_key=${TMDB_API_KEY}`)
|
||||||
|
// .then(res => {
|
||||||
|
// dispatch(retrieveMoviesGenresSuccess(res));
|
||||||
|
// })
|
||||||
|
// .catch(error => {
|
||||||
|
// console.log(error); //eslint-disable-line
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // POPULAR
|
||||||
|
// export function retrievePopularMoviesSuccess(res) {
|
||||||
|
// return {
|
||||||
|
// type: types.RETRIEVE_POPULAR_MOVIES_SUCCESS,
|
||||||
|
// popularMovies: res.data
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export function retrievePopularMovies(page) {
|
||||||
|
// return function (dispatch) {
|
||||||
|
// return axios.get(`${TMDB_URL}/movie/popular?api_key=${TMDB_API_KEY}&page=${page}`)
|
||||||
|
// .then(res => {
|
||||||
|
// dispatch(retrievePopularMoviesSuccess(res));
|
||||||
|
// })
|
||||||
|
// .catch(error => {
|
||||||
|
// console.log('Popular', error); //eslint-disable-line
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // NOW PLAYING
|
||||||
|
// export function retrieveNowPlayingMoviesSuccess(res) {
|
||||||
|
// return {
|
||||||
|
// type: types.RETRIEVE_NOWPLAYING_MOVIES_SUCCESS,
|
||||||
|
// nowPlayingMovies: res.data
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export function retrieveNowPlayingMovies(page) {
|
||||||
|
// return function (dispatch) {
|
||||||
|
// return axios.get(`${TMDB_URL}/movie/now_playing?api_key=${TMDB_API_KEY}&page=${page}`)
|
||||||
|
// .then(res => {
|
||||||
|
// dispatch(retrieveNowPlayingMoviesSuccess(res));
|
||||||
|
// })
|
||||||
|
// .catch(error => {
|
||||||
|
// console.log('Now Playing', error); //eslint-disable-line
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // MOVIES LIST
|
||||||
|
// export function retrieveMoviesListSuccess(res) {
|
||||||
|
// return {
|
||||||
|
// type: types.RETRIEVE_MOVIES_LIST_SUCCESS,
|
||||||
|
// list: res.data
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export function retrieveMoviesList(type, page) {
|
||||||
|
// return function (dispatch) {
|
||||||
|
// return axios.get(`${TMDB_URL}/movie/${type}?api_key=${TMDB_API_KEY}&page=${page}`)
|
||||||
|
// .then(res => {
|
||||||
|
// dispatch(retrieveMoviesListSuccess(res));
|
||||||
|
// })
|
||||||
|
// .catch(error => {
|
||||||
|
// console.log('Movies List', error); //eslint-disable-line
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // SEARCH RESULTS
|
||||||
|
// export function retrieveMoviesSearchResultsSuccess(res) {
|
||||||
|
// return {
|
||||||
|
// type: types.RETRIEVE_MOVIES_SEARCH_RESULT_SUCCESS,
|
||||||
|
// searchResults: res.data
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export function retrieveMoviesSearchResults(query, page) {
|
||||||
|
// return function (dispatch) {
|
||||||
|
// return axios.get(`${TMDB_URL}/search/movie?api_key=${TMDB_API_KEY}&query=${query}&page=${page}`)
|
||||||
|
// .then(res => {
|
||||||
|
// dispatch(retrieveMoviesSearchResultsSuccess(res));
|
||||||
|
// })
|
||||||
|
// .catch(error => {
|
||||||
|
// console.log('Movies Search Results', error); //eslint-disable-line
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // MOVIE DETAILS
|
||||||
|
// export function retrieveMovieDetailsSuccess(res) {
|
||||||
|
// return {
|
||||||
|
// type: types.RETRIEVE_MOVIE_DETAILS_SUCCESS,
|
||||||
|
// details: res.data
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export function retrieveMovieDetails(movieId) {
|
||||||
|
// return function (dispatch) {
|
||||||
|
// return axios.get(`${TMDB_URL}/movie/${movieId}?api_key=${TMDB_API_KEY}&append_to_response=casts,images,videos`)
|
||||||
|
// .then(res => {
|
||||||
|
// dispatch(retrieveMovieDetailsSuccess(res));
|
||||||
|
// })
|
||||||
|
// .catch(error => {
|
||||||
|
// console.log('Movie Details', error); //eslint-disable-line
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
// }
|
|
@ -0,0 +1,10 @@
|
||||||
|
// export const RETRIEVE_MOVIES_GENRES_SUCCESS = 'RETRIEVE_MOVIES_GENRES_SUCCESS';
|
||||||
|
|
||||||
|
// export const RETRIEVE_POPULAR_MOVIES_SUCCESS = 'RETRIEVE_POPULAR_MOVIES_SUCCESS';
|
||||||
|
// export const RETRIEVE_NOWPLAYING_MOVIES_SUCCESS = 'RETRIEVE_NOWPLAYING_MOVIES_SUCCESS';
|
||||||
|
// export const RETRIEVE_MOVIES_LIST_SUCCESS = 'RETRIEVE_MOVIES_LIST_SUCCESS';
|
||||||
|
// export const RETRIEVE_MOVIE_DETAILS_SUCCESS = 'RETRIEVE_MOVIE_DETAILS_SUCCESS';
|
||||||
|
// export const RETRIEVE_MOVIES_SEARCH_RESULT_SUCCESS = 'RETRIEVE_MOVIES_SEARCH_RESULT_SUCCESS';
|
||||||
|
|
||||||
|
export const SET_CURRENT_SERVER = 'SET_CURRENT_SERVER';
|
||||||
|
export const ESLINT_FIX = 'ESLINT_FIX';
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { createStore, applyMiddleware } from 'redux';
|
||||||
|
import thunk from 'redux-thunk';
|
||||||
|
import logger from 'redux-logger';
|
||||||
|
import rootReducer from '../reducers/rootReducer';
|
||||||
|
|
||||||
|
let middleware = [thunk];
|
||||||
|
|
||||||
|
if (__DEV__) {
|
||||||
|
/* eslint-disable global-require */
|
||||||
|
const reduxImmutableStateInvariant = require('redux-immutable-state-invariant').default();
|
||||||
|
middleware = [...middleware, reduxImmutableStateInvariant, logger];
|
||||||
|
} else {
|
||||||
|
middleware = [...middleware];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function configureStore(initialState) {
|
||||||
|
return createStore(
|
||||||
|
rootReducer,
|
||||||
|
initialState,
|
||||||
|
applyMiddleware(...middleware)
|
||||||
|
);
|
||||||
|
}
|
|
@ -70,20 +70,15 @@ const messagesSchema = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Realm.clearTestState();
|
|
||||||
|
|
||||||
const realm = new Realm({
|
const realm = new Realm({
|
||||||
schema: [settingsSchema, serversSchema, subscriptionSchema, messagesSchema, usersSchema]
|
schema: [settingsSchema, serversSchema, subscriptionSchema, messagesSchema, usersSchema]
|
||||||
});
|
});
|
||||||
|
|
||||||
export default realm;
|
export default realm;
|
||||||
|
|
||||||
// Clear settings
|
// Realm.clearTestState();
|
||||||
// realm.write(() => {
|
// realm.write(() => {
|
||||||
// // const allSettins = realm.objects('settings');
|
// realm.create('servers', { id: 'https://demo.rocket.chat', current: false }, true);
|
||||||
// // realm.delete(allSettins);
|
// realm.create('servers', { id: 'http://localhost:3000', current: false }, true);
|
||||||
//
|
// realm.create('servers', { id: 'http://10.0.2.2:3000', current: false }, true);
|
||||||
// // realm.create('servers', { id: 'https://demo.rocket.chat', current: false }, true);
|
|
||||||
// // realm.create('servers', { id: 'http://localhost:3000', current: false }, true);
|
|
||||||
// });
|
// });
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import Meteor from 'react-native-meteor';
|
import Meteor from 'react-native-meteor';
|
||||||
import Random from 'react-native-meteor/lib/Random';
|
import Random from 'react-native-meteor/lib/Random';
|
||||||
|
import { AsyncStorage } from 'react-native';
|
||||||
|
|
||||||
import realm from './realm';
|
import realm from './realm';
|
||||||
import debounce from '../utils/debounce';
|
import debounce from '../utils/debounce';
|
||||||
|
|
||||||
|
@ -32,13 +34,14 @@ const write = (() => {
|
||||||
run();
|
run();
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
const RocketChat = {
|
|
||||||
|
|
||||||
|
const RocketChat = {
|
||||||
createChannel({ name, users, type }) {
|
createChannel({ name, users, type }) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
Meteor.call(type ? 'createChannel' : 'createPrivateGroup', name, users, type, (err, res) => (err ? reject(err) : resolve(res)));
|
Meteor.call(type ? 'createChannel' : 'createPrivateGroup', name, users, type, (err, res) => (err ? reject(err) : resolve(res)));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
get currentServer() {
|
get currentServer() {
|
||||||
const current = realm.objects('servers').filtered('current = true').slice(0, 1)[0];
|
const current = realm.objects('servers').filtered('current = true').slice(0, 1)[0];
|
||||||
return current && current.id;
|
return current && current.id;
|
||||||
|
@ -51,6 +54,15 @@ const RocketChat = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async getUserToken() {
|
||||||
|
const TOKEN_KEY = 'reactnativemeteor_usertoken';
|
||||||
|
try {
|
||||||
|
return await AsyncStorage.getItem(TOKEN_KEY);
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(`AsyncStorage error: ${ error.message }`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
connect(cb) {
|
connect(cb) {
|
||||||
const url = `${ RocketChat.currentServer }/websocket`;
|
const url = `${ RocketChat.currentServer }/websocket`;
|
||||||
|
|
||||||
|
@ -94,6 +106,7 @@ const RocketChat = {
|
||||||
realm.create('messages', message, true);
|
realm.create('messages', message, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.subCache = this.subCache || {};
|
this.subCache = this.subCache || {};
|
||||||
this.roomCache = this.roomCache || {};
|
this.roomCache = this.roomCache || {};
|
||||||
this.cache = {};
|
this.cache = {};
|
||||||
|
@ -319,6 +332,7 @@ const RocketChat = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default RocketChat;
|
export default RocketChat;
|
||||||
|
|
||||||
Meteor.Accounts.onLogin(() => {
|
Meteor.Accounts.onLogin(() => {
|
||||||
Promise.all([call('subscriptions/get'), call('rooms/get')]).then(([subscriptions, rooms]) => {
|
Promise.all([call('subscriptions/get'), call('rooms/get')]).then(([subscriptions, rooms]) => {
|
||||||
subscriptions = subscriptions.sort((s1, s2) => (s1.rid > s2.rid ? 1 : -1));
|
subscriptions = subscriptions.sort((s1, s2) => (s1.rid > s2.rid ? 1 : -1));
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
import { Navigation } from 'react-native-navigation';
|
import { Navigation } from 'react-native-navigation';
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
|
||||||
import LoginView from './views/login';
|
import LoginView from './views/login';
|
||||||
import NewServerView from './views/serverNew';
|
import NewServerView from './views/serverNew';
|
||||||
import ListServerView from './views/serverList';
|
import ListServerView from './views/serverList';
|
||||||
import RoomsListView from './views/roomsList';
|
import RoomsListView from './views/roomsList';
|
||||||
import RoomView from './views/room';
|
import RoomView from './views/room';
|
||||||
import CreateChannel from './views/CreateChannel';
|
import CreateChannel from './views/CreateChannel';
|
||||||
|
import configureStore from './lib/createStore';
|
||||||
|
|
||||||
|
const store = configureStore();
|
||||||
|
|
||||||
Navigation.registerComponent('Rooms', () => RoomsListView);
|
Navigation.registerComponent('Rooms', () => RoomsListView, store, Provider);
|
||||||
Navigation.registerComponent('Room', () => RoomView);
|
Navigation.registerComponent('Room', () => RoomView, store, Provider);
|
||||||
Navigation.registerComponent('ListServer', () => ListServerView);
|
Navigation.registerComponent('ListServer', () => ListServerView, store, Provider);
|
||||||
Navigation.registerComponent('Login', () => LoginView);
|
Navigation.registerComponent('Login', () => LoginView, store, Provider);
|
||||||
Navigation.registerComponent('NewServer', () => NewServerView);
|
Navigation.registerComponent('NewServer', () => NewServerView, store, Provider);
|
||||||
Navigation.registerComponent('CreateChannel', () => CreateChannel);
|
Navigation.registerComponent('CreateChannel', () => CreateChannel, store, Provider);
|
||||||
|
|
||||||
Navigation.startSingleScreenApp({
|
Navigation.startSingleScreenApp({
|
||||||
screen: {
|
screen: {
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
import RocketChat from '../lib/rocketchat';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
server: RocketChat.currentServer,
|
||||||
|
login: {}
|
||||||
|
};
|
|
@ -0,0 +1,52 @@
|
||||||
|
import RocketChat from '../lib/rocketchat';
|
||||||
|
import * as types from '../constants/types';
|
||||||
|
import initialState from './initialState';
|
||||||
|
|
||||||
|
export default function(state = initialState, action) {
|
||||||
|
switch (action.type) {
|
||||||
|
case types.SET_CURRENT_SERVER:
|
||||||
|
RocketChat.currentServer = action.payload;
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
server: action.payload
|
||||||
|
};
|
||||||
|
|
||||||
|
// case types.RETRIEVE_POPULAR_MOVIES_SUCCESS:
|
||||||
|
// return {
|
||||||
|
// ...state,
|
||||||
|
// popularMovies: action.popularMovies
|
||||||
|
// };
|
||||||
|
|
||||||
|
// case types.RETRIEVE_NOWPLAYING_MOVIES_SUCCESS:
|
||||||
|
// return {
|
||||||
|
// ...state,
|
||||||
|
// nowPlayingMovies: action.nowPlayingMovies
|
||||||
|
// };
|
||||||
|
|
||||||
|
// case types.RETRIEVE_MOVIES_GENRES_SUCCESS:
|
||||||
|
// return {
|
||||||
|
// ...state,
|
||||||
|
// genres: action.moviesGenres
|
||||||
|
// };
|
||||||
|
|
||||||
|
// case types.RETRIEVE_MOVIES_LIST_SUCCESS:
|
||||||
|
// return {
|
||||||
|
// ...state,
|
||||||
|
// list: action.list
|
||||||
|
// };
|
||||||
|
|
||||||
|
// case types.RETRIEVE_MOVIE_DETAILS_SUCCESS:
|
||||||
|
// return {
|
||||||
|
// ...state,
|
||||||
|
// details: action.details
|
||||||
|
// };
|
||||||
|
|
||||||
|
// case types.RETRIEVE_MOVIES_SEARCH_RESULT_SUCCESS:
|
||||||
|
// return {
|
||||||
|
// ...state,
|
||||||
|
// searchResults: action.searchResults
|
||||||
|
// };
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
// import { combineReducers } from 'redux';
|
||||||
|
import reducers from './reducers';
|
||||||
|
|
||||||
|
// const rootReducer = combineReducers({
|
||||||
|
// reducers
|
||||||
|
// });
|
||||||
|
|
||||||
|
// export default rootReducer;
|
||||||
|
export default reducers;
|
|
@ -1,8 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { TextInput, StyleSheet } from 'react-native';
|
import { TextInput, StyleSheet } from 'react-native';
|
||||||
import RocketChat from '../lib/rocketchat';
|
import { connect } from 'react-redux';
|
||||||
|
import { bindActionCreators } from 'redux';
|
||||||
|
|
||||||
|
import * as actions from '../actions';
|
||||||
|
import RocketChat from '../lib/rocketchat';
|
||||||
import KeyboardView from '../components/KeyboardView';
|
import KeyboardView from '../components/KeyboardView';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
@ -25,9 +28,15 @@ const styles = StyleSheet.create({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@connect(state => ({
|
||||||
|
server: state.server
|
||||||
|
}), dispatch => ({
|
||||||
|
actions: bindActionCreators(actions, dispatch)
|
||||||
|
}))
|
||||||
export default class LoginView extends React.Component {
|
export default class LoginView extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
navigator: PropTypes.object.isRequired
|
navigator: PropTypes.object.isRequired,
|
||||||
|
server: PropTypes.string.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
static navigationOptions = () => ({
|
static navigationOptions = () => ({
|
||||||
|
@ -45,9 +54,11 @@ export default class LoginView extends React.Component {
|
||||||
this.props.navigator.setTitle({
|
this.props.navigator.setTitle({
|
||||||
title: 'Login'
|
title: 'Login'
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
this.props.navigator.setSubTitle({
|
this.props.navigator.setSubTitle({
|
||||||
subtitle: RocketChat.currentServer
|
subtitle: nextProps.server
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,10 @@ import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Text, View, StyleSheet, Button } from 'react-native';
|
import { Text, View, StyleSheet, Button } from 'react-native';
|
||||||
import { ListView } from 'realm/react-native';
|
import { ListView } from 'realm/react-native';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { bindActionCreators } from 'redux';
|
||||||
|
|
||||||
|
import * as actions from '../actions';
|
||||||
import realm from '../lib/realm';
|
import realm from '../lib/realm';
|
||||||
import RocketChat from '../lib/rocketchat';
|
import RocketChat from '../lib/rocketchat';
|
||||||
import debounce from '../utils/throttle';
|
import debounce from '../utils/throttle';
|
||||||
|
@ -37,12 +41,19 @@ const styles = StyleSheet.create({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@connect(state => ({
|
||||||
|
server: state.server
|
||||||
|
}), dispatch => ({
|
||||||
|
actions: bindActionCreators(actions, dispatch)
|
||||||
|
}))
|
||||||
export default class RoomView extends React.Component {
|
export default class RoomView extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
navigator: PropTypes.object.isRequired,
|
navigator: PropTypes.object.isRequired,
|
||||||
rid: PropTypes.string,
|
rid: PropTypes.string,
|
||||||
sid: PropTypes.string,
|
sid: PropTypes.string,
|
||||||
name: PropTypes.string
|
name: PropTypes.string,
|
||||||
|
server: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -50,7 +61,7 @@ export default class RoomView extends React.Component {
|
||||||
this.rid = props.rid || realm.objectForPrimaryKey('subscriptions', props.sid).rid;
|
this.rid = props.rid || realm.objectForPrimaryKey('subscriptions', props.sid).rid;
|
||||||
// this.rid = 'GENERAL';
|
// this.rid = 'GENERAL';
|
||||||
|
|
||||||
this.data = realm.objects('messages').filtered('_server.id = $0 AND rid = $1', RocketChat.currentServer, this.rid).sorted('ts', true);
|
this.data = realm.objects('messages').filtered('_server.id = $0 AND rid = $1', this.props.server, this.rid).sorted('ts', true);
|
||||||
this.state = {
|
this.state = {
|
||||||
dataSource: ds.cloneWithRows(this.data.slice(0, 10)),
|
dataSource: ds.cloneWithRows(this.data.slice(0, 10)),
|
||||||
loaded: true,
|
loaded: true,
|
||||||
|
|
|
@ -4,8 +4,12 @@ import { ListView } from 'realm/react-native';
|
||||||
import Icon from 'react-native-vector-icons/Ionicons';
|
import Icon from 'react-native-vector-icons/Ionicons';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Button, Text, View, StyleSheet, TouchableOpacity, Platform, TextInput } from 'react-native';
|
import { Text, View, StyleSheet, TouchableOpacity, Platform, TextInput } from 'react-native';
|
||||||
import Meteor from 'react-native-meteor';
|
import Meteor from 'react-native-meteor';
|
||||||
|
import { bindActionCreators } from 'redux';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import * as actions from '../actions';
|
||||||
import realm from '../lib/realm';
|
import realm from '../lib/realm';
|
||||||
import RocketChat from '../lib/rocketchat';
|
import RocketChat from '../lib/rocketchat';
|
||||||
import RoomItem from '../components/RoomItem';
|
import RoomItem from '../components/RoomItem';
|
||||||
|
@ -59,24 +63,17 @@ const styles = StyleSheet.create({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let setInitialData;
|
|
||||||
|
|
||||||
Meteor.getData().on('loggingIn', () => {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (Meteor._isLoggingIn === false && Meteor.userId() == null) {
|
|
||||||
console.log('loggingIn', Meteor.userId());
|
|
||||||
Navigation.showModal({
|
|
||||||
screen: 'Login',
|
|
||||||
animationType: 'slide-up'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
});
|
|
||||||
|
|
||||||
Meteor.Accounts.onLogin(() => {
|
Meteor.Accounts.onLogin(() => {
|
||||||
console.log('onLogin');
|
console.log('onLogin');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Meteor.Accounts.onLoginFailure(() => {
|
||||||
|
Navigation.showModal({
|
||||||
|
screen: 'Login',
|
||||||
|
animationType: 'slide-up'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
|
const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
|
||||||
class RoomsListItem extends React.PureComponent {
|
class RoomsListItem extends React.PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
@ -99,30 +96,21 @@ class RoomsListItem extends React.PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@connect(state => ({
|
||||||
|
server: state.server
|
||||||
|
}), dispatch => ({
|
||||||
|
actions: bindActionCreators(actions, dispatch)
|
||||||
|
}))
|
||||||
export default class RoomsListView extends React.Component {
|
export default class RoomsListView extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
navigator: PropTypes.object.isRequired
|
navigator: PropTypes.object.isRequired,
|
||||||
}
|
server: PropTypes.string
|
||||||
|
|
||||||
static navigationOptions = (props) => {
|
|
||||||
const server = RocketChat.currentServer ? RocketChat.currentServer.replace(/^https?:\/\//, '') : '';
|
|
||||||
const textAlign = Platform.OS === 'ios' ? 'center' : 'left';
|
|
||||||
const marginLeft = Platform.OS === 'ios' ? 0 : 20;
|
|
||||||
const position = Platform.OS === 'ios' ? 'headerLeft' : 'headerRight';
|
|
||||||
|
|
||||||
return {
|
|
||||||
headerTitle: <View style={{ height: 10, width: 200, top: -10, marginLeft }}>
|
|
||||||
<Text style={{ textAlign, fontSize: 16, fontWeight: '600' }}>Channels</Text>
|
|
||||||
<Text style={{ textAlign, fontSize: 10 }}>{server}</Text>
|
|
||||||
</View>,
|
|
||||||
title: 'Channels',
|
|
||||||
[position]: <Button title='Servers' onPress={() => props.navigation.navigate('ListServerModal')} />
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.data = realm.objects('subscriptions').filtered('_server.id = $0', RocketChat.currentServer).sorted('_updatedAt', true);
|
this.data = realm.objects('subscriptions').filtered('_server.id = $0', this.props.server).sorted('_updatedAt', true);
|
||||||
this.state = {
|
this.state = {
|
||||||
dataSource: ds.cloneWithRows(this.data.sorted('_updatedAt', true).slice(0, 10)),
|
dataSource: ds.cloneWithRows(this.data.sorted('_updatedAt', true).slice(0, 10)),
|
||||||
searching: false,
|
searching: false,
|
||||||
|
@ -134,26 +122,17 @@ export default class RoomsListView extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
setInitialData = this.setInitialData;
|
const button = Platform.OS === 'ios' ? 'leftButtons' : 'rightButtons';
|
||||||
|
|
||||||
if (RocketChat.currentServer) {
|
|
||||||
this.props.navigator.setSubTitle({
|
|
||||||
subtitle: RocketChat.currentServer
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.props.navigator.setButtons({
|
this.props.navigator.setButtons({
|
||||||
leftButtons: [{
|
[button]: [{
|
||||||
id: 'servers',
|
id: 'servers',
|
||||||
title: 'Servers'
|
title: 'Servers'
|
||||||
}],
|
}],
|
||||||
// rightButtons: [], // see "Adding buttons to the navigator" below for format (optional)
|
|
||||||
animated: true
|
animated: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// this.setInitialData();
|
if (this.props.server) {
|
||||||
if (RocketChat.currentServer) {
|
this.setInitialData();
|
||||||
RocketChat.connect();
|
|
||||||
} else {
|
} else {
|
||||||
Navigation.showModal({
|
Navigation.showModal({
|
||||||
screen: 'ListServer',
|
screen: 'ListServer',
|
||||||
|
@ -165,6 +144,14 @@ export default class RoomsListView extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
|
if (nextProps.server !== this.props.server) {
|
||||||
|
this.setInitialData(nextProps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUpdate
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.data.removeListener(this.updateState);
|
this.data.removeListener(this.updateState);
|
||||||
}
|
}
|
||||||
|
@ -194,7 +181,7 @@ export default class RoomsListView extends React.Component {
|
||||||
if (searchText !== '') {
|
if (searchText !== '') {
|
||||||
const dataSource = [];
|
const dataSource = [];
|
||||||
const usernames = [];
|
const usernames = [];
|
||||||
realm.objects('subscriptions').filtered('_server.id = $0 AND name CONTAINS[c] $1', RocketChat.currentServer, searchText).forEach((sub) => {
|
realm.objects('subscriptions').filtered('_server.id = $0 AND name CONTAINS[c] $1', this.props.server, searchText).forEach((sub) => {
|
||||||
dataSource.push(sub);
|
dataSource.push(sub);
|
||||||
|
|
||||||
if (sub.t === 'd') {
|
if (sub.t === 'd') {
|
||||||
|
@ -228,21 +215,36 @@ export default class RoomsListView extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setInitialData = () => {
|
|
||||||
if (this.data) {
|
|
||||||
this.data.removeListener(this.updateState);
|
|
||||||
}
|
|
||||||
this.data = realm.objects('subscriptions').filtered('_server.id = $0', RocketChat.currentServer).sorted('_updatedAt', true);
|
|
||||||
this.data.addListener(this.updateState);
|
|
||||||
|
|
||||||
this.updateState();
|
setInitialData = (props = this.props) => {
|
||||||
|
props.navigator.setSubTitle({
|
||||||
|
subtitle: props.server
|
||||||
|
});
|
||||||
|
|
||||||
|
RocketChat.getUserToken().then((token) => {
|
||||||
|
if (!token) {
|
||||||
|
Navigation.showModal({
|
||||||
|
screen: 'Login',
|
||||||
|
animationType: 'slide-up'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
RocketChat.connect();
|
||||||
|
|
||||||
|
if (this.data) {
|
||||||
|
this.data.removeListener(this.updateState);
|
||||||
|
}
|
||||||
|
this.data = realm.objects('subscriptions').filtered('_server.id = $0', props.server).sorted('_updatedAt', true);
|
||||||
|
this.data.addListener(this.updateState);
|
||||||
|
|
||||||
|
this.updateState();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getSubscriptions = () => this.data.sorted('_updatedAt', true)
|
getSubscriptions = () => this.data.sorted('_updatedAt', true)
|
||||||
|
|
||||||
updateState = debounce(() => {
|
updateState = debounce(() => {
|
||||||
this.setState({
|
this.setState({
|
||||||
dataSource: ds.cloneWithRows(this.data.filtered('_server.id = $0', RocketChat.currentServer))
|
dataSource: ds.cloneWithRows(this.data.filtered('_server.id = $0', this.props.server))
|
||||||
});
|
});
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
|
@ -266,7 +268,7 @@ export default class RoomsListView extends React.Component {
|
||||||
if (item.search) {
|
if (item.search) {
|
||||||
if (item.t === 'd') {
|
if (item.t === 'd') {
|
||||||
RocketChat.createDirectMessage(item.username)
|
RocketChat.createDirectMessage(item.username)
|
||||||
.then(room => realm.objects('subscriptions').filtered('_server.id = $0 AND rid = $1', RocketChat.currentServer, room.rid))
|
.then(room => realm.objects('subscriptions').filtered('_server.id = $0 AND rid = $1', this.props.server, room.rid))
|
||||||
.then(subs => navigateToRoom({ sid: subs[0]._id }))
|
.then(subs => navigateToRoom({ sid: subs[0]._id }))
|
||||||
.then(() => clearSearch());
|
.then(() => clearSearch());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Navigation } from 'react-native-navigation';
|
import { Navigation } from 'react-native-navigation';
|
||||||
|
import { bindActionCreators } from 'redux';
|
||||||
import Zeroconf from 'react-native-zeroconf';
|
import Zeroconf from 'react-native-zeroconf';
|
||||||
import { View, Text, SectionList, StyleSheet } from 'react-native';
|
import { View, Text, SectionList, Platform, StyleSheet } from 'react-native';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import * as actions from '../actions';
|
||||||
import realm from '../lib/realm';
|
import realm from '../lib/realm';
|
||||||
import RocketChat from '../lib/rocketchat';
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
view: {
|
view: {
|
||||||
|
@ -49,9 +51,17 @@ const styles = StyleSheet.create({
|
||||||
|
|
||||||
const zeroconf = new Zeroconf();
|
const zeroconf = new Zeroconf();
|
||||||
|
|
||||||
|
|
||||||
|
@connect(state => ({
|
||||||
|
server: state.server
|
||||||
|
}), dispatch => ({
|
||||||
|
actions: bindActionCreators(actions, dispatch)
|
||||||
|
}))
|
||||||
export default class ListServerView extends React.Component {
|
export default class ListServerView extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
navigator: PropTypes.object.isRequired
|
navigator: PropTypes.object.isRequired,
|
||||||
|
actions: PropTypes.object,
|
||||||
|
server: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -59,15 +69,6 @@ export default class ListServerView extends React.Component {
|
||||||
this.state = {
|
this.state = {
|
||||||
sections: []
|
sections: []
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
componentWillMount() {
|
|
||||||
realm.addListener('change', this.updateState);
|
|
||||||
zeroconf.on('update', this.updateState);
|
|
||||||
|
|
||||||
zeroconf.scan('http', 'tcp', 'local.');
|
|
||||||
|
|
||||||
this.state = this.getState();
|
|
||||||
|
|
||||||
this.props.navigator.setTitle({
|
this.props.navigator.setTitle({
|
||||||
title: 'Servers'
|
title: 'Servers'
|
||||||
|
@ -78,12 +79,29 @@ export default class ListServerView extends React.Component {
|
||||||
id: 'add',
|
id: 'add',
|
||||||
title: 'Add'
|
title: 'Add'
|
||||||
}],
|
}],
|
||||||
|
leftButtons: props.server && Platform.select({
|
||||||
|
ios: [{
|
||||||
|
id: 'close',
|
||||||
|
title: 'Close'
|
||||||
|
}]
|
||||||
|
}),
|
||||||
animated: true
|
animated: true
|
||||||
});
|
});
|
||||||
|
|
||||||
this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));
|
this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
realm.addListener('change', this.updateState);
|
||||||
|
zeroconf.on('update', this.updateState);
|
||||||
|
|
||||||
|
zeroconf.scan('http', 'tcp', 'local.');
|
||||||
|
|
||||||
|
this.state = this.getState();
|
||||||
|
|
||||||
|
this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
zeroconf.stop();
|
zeroconf.stop();
|
||||||
realm.removeListener('change', this.updateState);
|
realm.removeListener('change', this.updateState);
|
||||||
|
@ -105,18 +123,20 @@ export default class ListServerView extends React.Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event.id === 'didDisappear' && this.state.server) {
|
||||||
|
this.props.actions.setCurrentServer(this.state.server);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onPressItem = (item) => {
|
onPressItem = (item) => {
|
||||||
RocketChat.currentServer = item.id;
|
|
||||||
|
|
||||||
RocketChat.connect();
|
|
||||||
|
|
||||||
Navigation.dismissModal({
|
Navigation.dismissModal({
|
||||||
animationType: 'slide-down'
|
animationType: 'slide-down'
|
||||||
});
|
});
|
||||||
// this.props.navigation.state.params.onSelect();
|
|
||||||
// this.props.navigation.dispatch({ type: 'Navigation/BACK' });
|
this.setState({
|
||||||
|
server: item.id
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getState = () => {
|
getState = () => {
|
||||||
|
|
|
@ -4,8 +4,6 @@ import { Navigation } from 'react-native-navigation';
|
||||||
import { Text, TextInput, View, StyleSheet } from 'react-native';
|
import { Text, TextInput, View, StyleSheet } from 'react-native';
|
||||||
import _ from 'underscore';
|
import _ from 'underscore';
|
||||||
|
|
||||||
import RocketChat from '../lib/rocketchat';
|
|
||||||
|
|
||||||
import KeyboardView from '../components/KeyboardView';
|
import KeyboardView from '../components/KeyboardView';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
@ -49,6 +47,7 @@ const styles = StyleSheet.create({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
export default class NewServerView extends React.Component {
|
export default class NewServerView extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
navigator: PropTypes.object.isRequired
|
navigator: PropTypes.object.isRequired
|
||||||
|
@ -80,7 +79,6 @@ export default class NewServerView extends React.Component {
|
||||||
|
|
||||||
this.inputElement.blur();
|
this.inputElement.blur();
|
||||||
this.validateServer(url).then(() => {
|
this.validateServer(url).then(() => {
|
||||||
RocketChat.currentServer = url;
|
|
||||||
Navigation.dismissModal({
|
Navigation.dismissModal({
|
||||||
animationType: 'slide-down'
|
animationType: 'slide-down'
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"allowJs": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"allowSyntheticDefaultImports": true
|
"experimentalDecorators": true
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules"
|
"node_modules"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
"android": "react-native run-android"
|
"android": "react-native run-android"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"babel-plugin-transform-decorators-legacy": "^1.3.4",
|
||||||
"prop-types": "^15.5.10",
|
"prop-types": "^15.5.10",
|
||||||
"react": "16.0.0-alpha.12",
|
"react": "16.0.0-alpha.12",
|
||||||
"react-emojione": "^3.1.10",
|
"react-emojione": "^3.1.10",
|
||||||
|
@ -33,7 +34,12 @@
|
||||||
"react-native-vector-icons": "^4.3.0",
|
"react-native-vector-icons": "^4.3.0",
|
||||||
"react-native-zeroconf": "^0.8.1",
|
"react-native-zeroconf": "^0.8.1",
|
||||||
"react-navigation": "^1.0.0-beta.11",
|
"react-navigation": "^1.0.0-beta.11",
|
||||||
|
"react-redux": "^5.0.6",
|
||||||
"realm": "^1.10.1",
|
"realm": "^1.10.1",
|
||||||
|
"redux": "^3.7.2",
|
||||||
|
"redux-immutable-state-invariant": "^2.0.0",
|
||||||
|
"redux-logger": "^3.0.6",
|
||||||
|
"redux-thunk": "^2.2.0",
|
||||||
"strip-ansi": "^4.0.0",
|
"strip-ansi": "^4.0.0",
|
||||||
"underscore": "^1.8.3"
|
"underscore": "^1.8.3"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue