[WIP] Abstract database calls (#157)

* Databases separated
This commit is contained in:
Diego Mello 2017-12-27 13:22:06 -02:00 committed by Guilherme Gazzo
parent f229ab730f
commit b9ca7abb52
25 changed files with 184 additions and 145 deletions

View File

@ -489,6 +489,7 @@ exports[`render unread +999 1`] = `
> >
NA NA
</Text> </Text>
</View> </View>
<View <View
style={ style={
@ -635,6 +636,7 @@ exports[`render unread 1`] = `
> >
NA NA
</Text> </Text>
</View> </View>
<View <View
style={ style={
@ -781,6 +783,7 @@ exports[`renders correctly 1`] = `
> >
NA NA
</Text> </Text>
</View> </View>
<View <View
style={ style={

View File

@ -38,6 +38,7 @@ exports[`Storyshots Avatar avatar 1`] = `
> >
TE TE
</Text> </Text>
</View> </View>
<View <View
style={ style={
@ -74,6 +75,7 @@ exports[`Storyshots Avatar avatar 1`] = `
> >
AA AA
</Text> </Text>
</View> </View>
<View <View
style={ style={
@ -110,6 +112,7 @@ exports[`Storyshots Avatar avatar 1`] = `
> >
BB BB
</Text> </Text>
</View> </View>
<View <View
style={ style={
@ -146,6 +149,7 @@ exports[`Storyshots Avatar avatar 1`] = `
> >
TE TE
</Text> </Text>
</View> </View>
</View> </View>
</RCTScrollView> </RCTScrollView>
@ -229,6 +233,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
> >
RC RC
</Text> </Text>
</View> </View>
<View <View
style={ style={
@ -350,6 +355,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
> >
RC RC
</Text> </Text>
</View> </View>
<View <View
style={ style={
@ -473,6 +479,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
> >
RC RC
</Text> </Text>
</View> </View>
<View <View
style={ style={
@ -614,6 +621,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
> >
LC LC
</Text> </Text>
</View> </View>
<View <View
style={ style={
@ -757,6 +765,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
> >
LC LC
</Text> </Text>
</View> </View>
<View <View
style={ style={
@ -898,6 +907,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
> >
LC LC
</Text> </Text>
</View> </View>
<View <View
style={ style={
@ -1039,6 +1049,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
> >
LC LC
</Text> </Text>
</View> </View>
<View <View
style={ style={
@ -1180,6 +1191,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
> >
LC LC
</Text> </Text>
</View> </View>
<View <View
style={ style={
@ -1321,6 +1333,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
> >
W W
</Text> </Text>
</View> </View>
<View <View
style={ style={
@ -1442,6 +1455,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
> >
WW WW
</Text> </Text>
</View> </View>
<View <View
style={ style={
@ -1563,6 +1577,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
> >
</Text> </Text>
</View> </View>
<View <View
style={ style={

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -19,6 +19,12 @@ export function setCurrentServer(server) {
}; };
} }
export function addSettings(settings) {
return {
type: types.ADD_SETTINGS,
payload: settings
};
}
export function setAllSettings(settings) { export function setAllSettings(settings) {
return { return {
type: types.SET_ALL_SETTINGS, type: types.SET_ALL_SETTINGS,

View File

@ -1,3 +1,4 @@
export const SET_CURRENT_SERVER = 'SET_CURRENT_SERVER'; export const SET_CURRENT_SERVER = 'SET_CURRENT_SERVER';
export const SET_ALL_SETTINGS = 'SET_ALL_SETTINGS'; export const SET_ALL_SETTINGS = 'SET_ALL_SETTINGS';
export const SET_ALL_PERMISSIONS = 'SET_ALL_PERMISSIONS'; export const SET_ALL_PERMISSIONS = 'SET_ALL_PERMISSIONS';
export const ADD_SETTINGS = 'ADD_SETTINGS';

View File

@ -21,7 +21,7 @@ const styles = StyleSheet.create({
}); });
@connect(state => ({ @connect(state => ({
baseUrl: state.settings.Site_Url baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
})) }))
class Avatar extends React.PureComponent { class Avatar extends React.PureComponent {

View File

@ -9,7 +9,7 @@ import RocketChat from '../../lib/rocketchat';
import { editRequest, editCancel, clearInput } from '../../actions/messages'; import { editRequest, editCancel, clearInput } from '../../actions/messages';
import styles from './style'; import styles from './style';
import MyIcon from '../icons'; import MyIcon from '../icons';
import realm from '../../lib/realm'; import database from '../../lib/realm';
import Avatar from '../Avatar'; import Avatar from '../Avatar';
import AnimatedContainer from './AnimatedContainer'; import AnimatedContainer from './AnimatedContainer';
@ -23,7 +23,7 @@ const onlyUnique = function onlyUnique(value, index, self) {
room: state.room, room: state.room,
message: state.messages.message, message: state.messages.message,
editing: state.messages.editing, editing: state.messages.editing,
baseUrl: state.settings.Site_Url baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
}), dispatch => ({ }), dispatch => ({
editCancel: () => dispatch(editCancel()), editCancel: () => dispatch(editCancel()),
editRequest: message => dispatch(editRequest(message)), editRequest: message => dispatch(editRequest(message)),
@ -200,7 +200,7 @@ export default class MessageBox extends React.Component {
} }
async _getUsers(keyword) { async _getUsers(keyword) {
this.users = realm.objects('users'); this.users = database.objects('users');
if (keyword) { if (keyword) {
this.users = this.users.filtered('username CONTAINS[c] $0', keyword); this.users = this.users.filtered('username CONTAINS[c] $0', keyword);
} }
@ -222,28 +222,24 @@ export default class MessageBox extends React.Component {
RocketChat.spotlight(keyword, usernames, { users: true }), RocketChat.spotlight(keyword, usernames, { users: true }),
new Promise((resolve, reject) => (this.oldPromise = reject)) new Promise((resolve, reject) => (this.oldPromise = reject))
]); ]);
realm.write(() => { database.write(() => {
results.users.forEach((user) => { results.users.forEach((user) => {
user._server = { database.create('users', user, true);
id: this.props.baseUrl,
current: true
};
realm.create('users', user, true);
}); });
}); });
} catch (e) { } catch (e) {
console.log('spotlight canceled'); console.log('spotlight canceled');
} finally { } finally {
delete this.oldPromise; delete this.oldPromise;
this.users = realm.objects('users').filtered('username CONTAINS[c] $0', keyword); this.users = database.objects('users').filtered('username CONTAINS[c] $0', keyword);
this.setState({ mentions: this.users.slice() }); this.setState({ mentions: this.users.slice() });
} }
} }
async _getRooms(keyword = '') { async _getRooms(keyword = '') {
this.roomsCache = this.roomsCache || []; this.roomsCache = this.roomsCache || [];
this.rooms = realm.objects('subscriptions') this.rooms = database.objects('subscriptions')
.filtered('_server.id = $0 AND t != $1', this.props.baseUrl, 'd'); .filtered('t != $0', 'd');
if (keyword) { if (keyword) {
this.rooms = this.rooms.filtered('name CONTAINS[c] $0', keyword); this.rooms = this.rooms.filtered('name CONTAINS[c] $0', keyword);
} }

View File

@ -5,7 +5,7 @@ import ActionSheet from 'react-native-actionsheet';
import { errorActionsHide } from '../actions/messages'; import { errorActionsHide } from '../actions/messages';
import RocketChat from '../lib/rocketchat'; import RocketChat from '../lib/rocketchat';
import realm from '../lib/realm'; import database from '../lib/realm';
@connect( @connect(
state => ({ state => ({
@ -41,9 +41,9 @@ export default class MessageActions extends React.Component {
handleResend = () => RocketChat.resendMessage(this.props.actionMessage._id); handleResend = () => RocketChat.resendMessage(this.props.actionMessage._id);
handleDelete = () => { handleDelete = () => {
realm.write(() => { database.write(() => {
const msg = realm.objects('messages').filtered('_id = $0', this.props.actionMessage._id); const msg = database.objects('messages').filtered('_id = $0', this.props.actionMessage._id);
realm.delete(msg); database.delete(msg);
}); });
} }

View File

@ -31,13 +31,13 @@ export default class Routes extends React.Component {
} }
componentDidMount() { componentDidMount() {
if (!this.props.app.starting) { if (this.props.app.ready) {
SplashScreen.hide(); SplashScreen.hide();
} }
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
if (!nextProps.app.starting && this.props.app.starting !== nextProps.app.starting) { if (nextProps.app.ready && this.props.app.ready !== nextProps.app.ready) {
SplashScreen.hide(); SplashScreen.hide();
} }
} }
@ -49,6 +49,10 @@ export default class Routes extends React.Component {
render() { render() {
const { login } = this.props; const { login } = this.props;
if (this.props.app.starting) {
return null;
}
if (!login.token || login.isRegistering) { if (!login.token || login.isRegistering) {
return (<PublicRoutes ref={nav => this.navigator = nav} />); return (<PublicRoutes ref={nav => this.navigator = nav} />);
} }

View File

@ -4,7 +4,7 @@ import { ScrollView, Text, View, StyleSheet, FlatList, TouchableHighlight } from
import { DrawerItems } from 'react-navigation'; import { DrawerItems } from 'react-navigation';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import realm from '../lib/realm'; import database from '../lib/realm';
import { setServer, gotoAddServer } from '../actions/server'; import { setServer, gotoAddServer } from '../actions/server';
import { logout } from '../actions/login'; import { logout } from '../actions/login';
@ -54,12 +54,12 @@ export default class Sidebar extends Component {
} }
componentWillMount() { componentWillMount() {
realm.addListener('change', this.updateState); realm.databases.serversDB.addListener('change', this.updateState);
this.setState(this.getState()); this.setState(this.getState());
} }
componentWillUnmount() { componentWillUnmount() {
realm.removeListener('change', this.updateState); realm.databases.serversDB.removeListener('change', this.updateState);
} }
onItemPress = ({ route, focused }) => { onItemPress = ({ route, focused }) => {
@ -75,7 +75,7 @@ export default class Sidebar extends Component {
} }
getState = () => ({ getState = () => ({
servers: realm.objects('servers') servers: realm.databases.serversDB.objects('servers')
}) })
updateState = () => { updateState = () => {

View File

@ -1,5 +1,8 @@
import Realm from 'realm'; import Realm from 'realm';
// import { AsyncStorage } from 'react-native'; // import { AsyncStorage } from 'react-native';
// Realm.clearTestState();
// AsyncStorage.clear();
const serversSchema = { const serversSchema = {
name: 'servers', name: 'servers',
@ -15,7 +18,6 @@ const settingsSchema = {
primaryKey: '_id', primaryKey: '_id',
properties: { properties: {
_id: 'string', _id: 'string',
_server: 'servers',
valueAsString: { type: 'string', optional: true }, valueAsString: { type: 'string', optional: true },
valueAsBoolean: { type: 'bool', optional: true }, valueAsBoolean: { type: 'bool', optional: true },
valueAsNumber: { type: 'int', optional: true }, valueAsNumber: { type: 'int', optional: true },
@ -36,7 +38,6 @@ const permissionsSchema = {
primaryKey: '_id', primaryKey: '_id',
properties: { properties: {
_id: 'string', _id: 'string',
_server: 'servers',
roles: { type: 'list', objectType: 'permissionsRoles' }, roles: { type: 'list', objectType: 'permissionsRoles' },
_updatedAt: { type: 'date', optional: true } _updatedAt: { type: 'date', optional: true }
} }
@ -47,7 +48,6 @@ const roomsSchema = {
primaryKey: '_id', primaryKey: '_id',
properties: { properties: {
_id: 'string', _id: 'string',
_server: 'servers',
t: 'string', t: 'string',
_updatedAt: { type: 'date', optional: true } _updatedAt: { type: 'date', optional: true }
} }
@ -65,7 +65,6 @@ const subscriptionSchema = {
primaryKey: '_id', primaryKey: '_id',
properties: { properties: {
_id: 'string', _id: 'string',
_server: 'servers',
f: { type: 'bool', optional: true }, f: { type: 'bool', optional: true },
t: 'string', t: 'string',
ts: { type: 'date', optional: true }, ts: { type: 'date', optional: true },
@ -89,7 +88,6 @@ const usersSchema = {
primaryKey: '_id', primaryKey: '_id',
properties: { properties: {
_id: 'string', _id: 'string',
_server: 'servers',
username: 'string', username: 'string',
name: { type: 'string', optional: true } name: { type: 'string', optional: true }
} }
@ -157,7 +155,6 @@ const messagesSchema = {
primaryKey: '_id', primaryKey: '_id',
properties: { properties: {
_id: 'string', _id: 'string',
_server: 'servers',
msg: { type: 'string', optional: true }, msg: { type: 'string', optional: true },
t: { type: 'string', optional: true }, t: { type: 'string', optional: true },
rid: 'string', rid: 'string',
@ -178,28 +175,56 @@ const messagesSchema = {
editedBy: 'messagesEditedBy' editedBy: 'messagesEditedBy'
} }
}; };
// const schema = [
// Realm.clearTestState(); settingsSchema,
// AsyncStorage.clear(); subscriptionSchema,
const realm = new Realm({ subscriptionRolesSchema,
schema: [ messagesSchema,
settingsSchema, usersSchema,
serversSchema, roomsSchema,
subscriptionSchema, attachment,
subscriptionRolesSchema, attachmentFields,
messagesSchema, messagesEditedBySchema,
usersSchema, permissionsSchema,
roomsSchema, permissionsRolesSchema,
attachment, url
attachmentFields, ];
messagesEditedBySchema, class DB {
permissionsSchema, databases = {
permissionsRolesSchema, serversDB: new Realm({
url path: 'default.realm',
], schema: [
deleteRealmIfMigrationNeeded: true serversSchema
}); ],
export default realm; deleteRealmIfMigrationNeeded: true
})
};
deleteAll(...args) {
return this.database.write(() => this.database.deleteAll(...args));
}
write(...args) {
return this.database.write(...args);
}
create(...args) {
return this.database.create(...args);
}
objects(...args) {
return this.database.objects(...args);
}
get database() {
return this.databases.activeDB;
}
setActiveDB(database) {
const path = database.replace(/(^\w+:|^)\/\//, '');
return this.databases.activeDB = new Realm({
path: `${ path }.realm`,
schema,
deleteRealmIfMigrationNeeded: true
});
}
}
export default new DB();
// realm.write(() => { // realm.write(() => {
// realm.create('servers', { id: 'https://open.rocket.chat', current: false }, true); // realm.create('servers', { id: 'https://open.rocket.chat', current: false }, true);

View File

@ -6,7 +6,7 @@ import RNFetchBlob from 'react-native-fetch-blob';
import reduxStore from './createStore'; import reduxStore from './createStore';
import settingsType from '../constants/settings'; import settingsType from '../constants/settings';
import messagesStatus from '../constants/messagesStatus'; import messagesStatus from '../constants/messagesStatus';
import realm from './realm'; import database from './realm';
import * as actions from '../actions'; import * as actions from '../actions';
import { someoneTyping } from '../actions/room'; import { someoneTyping } from '../actions/room';
import { setUser } from '../actions/login'; import { setUser } from '../actions/login';
@ -77,7 +77,9 @@ const RocketChat = {
this.ddp.on('disconnected', () => { this.ddp.on('disconnected', () => {
reduxStore.dispatch(disconnect()); reduxStore.dispatch(disconnect());
}); });
this.ddp.on('open', async() => resolve(reduxStore.dispatch(connectSuccess()))); this.ddp.on('open', async() => {
resolve(reduxStore.dispatch(connectSuccess()));
});
this.ddp.on('connected', () => { this.ddp.on('connected', () => {
RocketChat.getSettings(); RocketChat.getSettings();
RocketChat.getPermissions(); RocketChat.getPermissions();
@ -90,16 +92,15 @@ const RocketChat = {
this.ddp.on('connected', () => this.ddp.subscribe('activeUsers', null, false)); this.ddp.on('connected', () => this.ddp.subscribe('activeUsers', null, false));
this.ddp.on('users', (ddpMessage) => { this.ddp.on('users', (ddpMessage) => {
if (ddpMessage.collection === 'users') { if (ddpMessage.collection === 'users') {
return RocketChat._setUser(ddpMessage); return RocketChat._setUser(ddpMessage);
} }
}); });
this.ddp.on('stream-room-messages', ddpMessage => realm.write(() => { this.ddp.on('stream-room-messages', ddpMessage => database.write(() => {
const message = this._buildMessage(ddpMessage.fields.args[0]); const message = this._buildMessage(ddpMessage.fields.args[0]);
realm.create('messages', message, true); database.create('messages', message, true);
})); }));
this.ddp.on('stream-notify-room', (ddpMessage) => { this.ddp.on('stream-notify-room', (ddpMessage) => {
@ -117,13 +118,13 @@ const RocketChat = {
if (data.roles) { if (data.roles) {
data.roles = data.roles.map(role => ({ value: role })); data.roles = data.roles.map(role => ({ value: role }));
} }
realm.write(() => { database.write(() => {
realm.create('subscriptions', data, true); database.create('subscriptions', data, true);
}); });
} }
if (/rooms/.test(ev) && type === 'updated') { if (/rooms/.test(ev) && type === 'updated') {
const sub = realm.objects('subscriptions').filtered('rid == $0', data._id)[0]; const sub = database.objects('subscriptions').filtered('rid == $0', data._id)[0];
realm.write(() => { database.write(() => {
sub.roomUpdatedAt = data._updatedAt; sub.roomUpdatedAt = data._updatedAt;
}); });
} }
@ -208,20 +209,11 @@ const RocketChat = {
}, },
loadSubscriptions(cb) { loadSubscriptions(cb) {
const { server } = reduxStore.getState().server;
this.ddp.call('subscriptions/get').then((data) => { this.ddp.call('subscriptions/get').then((data) => {
if (data.length) { if (data.length) {
realm.write(() => { database.write(() => {
data.forEach((subscription) => { data.forEach((subscription) => {
// const subscription = { database.create('subscriptions', subscription, true);
// _id: item._id
// };
// if (typeof item.value === 'string') {
// subscription.value = item.value;
// }
subscription._server = { id: server };
// write('subscriptions', subscription);
realm.create('subscriptions', subscription, true);
}); });
}); });
} }
@ -262,9 +254,7 @@ const RocketChat = {
}); });
}, },
_buildMessage(message) { _buildMessage(message) {
const { server } = reduxStore.getState().server;
message.status = messagesStatus.SENT; message.status = messagesStatus.SENT;
message._server = { id: server };
message.attachments = message.attachments || []; message.attachments = message.attachments || [];
if (message.urls) { if (message.urls) {
message.urls = RocketChat._parseUrls(message.urls); message.urls = RocketChat._parseUrls(message.urls);
@ -278,9 +268,9 @@ const RocketChat = {
return this.ddp.call('loadHistory', rid, end, 20).then((data) => { return this.ddp.call('loadHistory', rid, end, 20).then((data) => {
if (data && data.messages.length) { if (data && data.messages.length) {
const messages = data.messages.map(message => this._buildMessage(message)); const messages = data.messages.map(message => this._buildMessage(message));
realm.write(() => { database.write(() => {
messages.forEach((message) => { messages.forEach((message) => {
realm.create('messages', message, true); database.create('messages', message, true);
}); });
}); });
} }
@ -300,7 +290,6 @@ const RocketChat = {
getMessage(rid, msg = {}) { getMessage(rid, msg = {}) {
const _id = Random.id(); const _id = Random.id();
// console.log('reduxStore.getState().login.id ', reduxStore.getState().login);
const message = { const message = {
_id, _id,
rid, rid,
@ -308,16 +297,14 @@ const RocketChat = {
ts: new Date(), ts: new Date(),
_updatedAt: new Date(), _updatedAt: new Date(),
status: messagesStatus.TEMP, status: messagesStatus.TEMP,
_server: { id: reduxStore.getState().server.server },
u: { u: {
_id: reduxStore.getState().login.user.id || '1', _id: reduxStore.getState().login.user.id || '1',
username: reduxStore.getState().login.user.username username: reduxStore.getState().login.user.username
} }
}; };
realm.write(() => { database.write(() => {
realm.create('messages', message, true); database.create('messages', message, true);
// write('messages', message, true);
}); });
return message; return message;
}, },
@ -327,9 +314,9 @@ const RocketChat = {
const timeoutCall = new Promise(resolve => setTimeout(resolve, SERVER_TIMEOUT, 'timeout')); const timeoutCall = new Promise(resolve => setTimeout(resolve, SERVER_TIMEOUT, 'timeout'));
const result = await Promise.race([sendMessageCall, timeoutCall]); const result = await Promise.race([sendMessageCall, timeoutCall]);
if (result === 'timeout') { if (result === 'timeout') {
realm.write(() => { database.write(() => {
message.status = messagesStatus.ERROR; message.status = messagesStatus.ERROR;
realm.create('messages', message, true); database.create('messages', message, true);
}); });
} }
}, },
@ -338,10 +325,10 @@ const RocketChat = {
return RocketChat._sendMessageCall(tempMessage); return RocketChat._sendMessageCall(tempMessage);
}, },
async resendMessage(messageId) { async resendMessage(messageId) {
const message = await realm.objects('messages').filtered('_id = $0', messageId)[0]; const message = await database.objects('messages').filtered('_id = $0', messageId)[0];
realm.write(() => { database.write(() => {
message.status = messagesStatus.TEMP; message.status = messagesStatus.TEMP;
realm.create('messages', message, true); database.create('messages', message, true);
}); });
return RocketChat._sendMessageCall(message); return RocketChat._sendMessageCall(message);
}, },
@ -413,17 +400,16 @@ const RocketChat = {
} catch (e) { } catch (e) {
return e; return e;
} finally { } finally {
realm.write(() => { database.write(() => {
const msg = realm.objects('messages').filtered('_id = $0', placeholder._id); const msg = database.objects('messages').filtered('_id = $0', placeholder._id);
realm.delete(msg); database.delete(msg);
}); });
} }
}, },
async getRooms() { async getRooms() {
const { server, login } = reduxStore.getState(); const { login } = reduxStore.getState();
let lastMessage = realm let lastMessage = database
.objects('subscriptions') .objects('subscriptions')
.filtered('_server.id = $0', server.server)
.sorted('roomUpdatedAt', true)[0]; .sorted('roomUpdatedAt', true)[0];
lastMessage = lastMessage && new Date(lastMessage.roomUpdatedAt); lastMessage = lastMessage && new Date(lastMessage.roomUpdatedAt);
let [subscriptions, rooms] = await Promise.all([call('subscriptions/get', lastMessage), call('rooms/get', lastMessage)]); let [subscriptions, rooms] = await Promise.all([call('subscriptions/get', lastMessage), call('rooms/get', lastMessage)]);
@ -441,12 +427,11 @@ const RocketChat = {
if (subscription.roles) { if (subscription.roles) {
subscription.roles = subscription.roles.map(role => ({ value: role })); subscription.roles = subscription.roles.map(role => ({ value: role }));
} }
subscription._server = { id: server.server };
return subscription; return subscription;
}); });
realm.write(() => { database.write(() => {
data.forEach(subscription => data.forEach(subscription =>
realm.create('subscriptions', subscription, true)); database.create('subscriptions', subscription, true));
}); });
this.ddp.subscribe('stream-notify-user', `${ login.user.id }/subscriptions-changed`, false); this.ddp.subscribe('stream-notify-user', `${ login.user.id }/subscriptions-changed`, false);
this.ddp.subscribe('stream-notify-user', `${ login.user.id }/rooms-changed`, false); this.ddp.subscribe('stream-notify-user', `${ login.user.id }/rooms-changed`, false);
@ -481,20 +466,20 @@ const RocketChat = {
logout({ server }) { logout({ server }) {
if (this.ddp) { if (this.ddp) {
this.ddp.logout(); this.ddp.logout();
// this.disconnect();
} }
database.deleteAll();
AsyncStorage.removeItem(TOKEN_KEY); AsyncStorage.removeItem(TOKEN_KEY);
AsyncStorage.removeItem(`${ TOKEN_KEY }-${ server }`); AsyncStorage.removeItem(`${ TOKEN_KEY }-${ server }`);
}, },
async getSettings() { async getSettings() {
const temp = realm.objects('settings').sorted('_updatedAt', true)[0]; const temp = database.objects('settings').sorted('_updatedAt', true)[0];
const result = await (!temp ? call('public-settings/get') : call('public-settings/get', new Date(temp._updatedAt))); const result = await (!temp ? call('public-settings/get') : call('public-settings/get', new Date(temp._updatedAt)));
const settings = temp ? result.update : result; const settings = temp ? result.update : result;
const filteredSettings = RocketChat._prepareSettings(RocketChat._filterSettings(settings)); const filteredSettings = RocketChat._prepareSettings(RocketChat._filterSettings(settings));
realm.write(() => { database.write(() => {
filteredSettings.forEach(setting => realm.create('settings', setting, true)); filteredSettings.forEach(setting => database.create('settings', setting, true));
}); });
reduxStore.dispatch(actions.setAllSettings(RocketChat.parseSettings(filteredSettings))); reduxStore.dispatch(actions.addSettings(RocketChat.parseSettings(filteredSettings)));
}, },
parseSettings: settings => settings.reduce((ret, item) => { parseSettings: settings => settings.reduce((ret, item) => {
ret[item._id] = item[settingsType[item.type]] || item.valueAsString || item.valueAsNumber || ret[item._id] = item[settingsType[item.type]] || item.valueAsString || item.valueAsNumber ||
@ -509,12 +494,12 @@ const RocketChat = {
}, },
_filterSettings: settings => settings.filter(setting => settingsType[setting.type] && setting.value), _filterSettings: settings => settings.filter(setting => settingsType[setting.type] && setting.value),
async getPermissions() { async getPermissions() {
const temp = realm.objects('permissions').sorted('_updatedAt', true)[0]; const temp = database.objects('permissions').sorted('_updatedAt', true)[0];
const result = await (!temp ? call('permissions/get') : call('permissions/get', new Date(temp._updatedAt))); const result = await (!temp ? call('permissions/get') : call('permissions/get', new Date(temp._updatedAt)));
let permissions = temp ? result.update : result; let permissions = temp ? result.update : result;
permissions = RocketChat._preparePermissions(permissions); permissions = RocketChat._preparePermissions(permissions);
realm.write(() => { database.write(() => {
permissions.forEach(permission => realm.create('permissions', permission, true)); permissions.forEach(permission => database.create('permissions', permission, true));
}); });
reduxStore.dispatch(actions.setAllPermissions(RocketChat.parsePermissions(permissions))); reduxStore.dispatch(actions.setAllPermissions(RocketChat.parsePermissions(permissions)));
}, },
@ -545,7 +530,7 @@ const RocketChat = {
return call('pinMessage', message); return call('pinMessage', message);
}, },
getRoom(rid) { getRoom(rid) {
const result = realm.objects('subscriptions').filtered('rid = $0', rid); const result = database.objects('subscriptions').filtered('rid = $0', rid);
if (result.length === 0) { if (result.length === 0) {
return Promise.reject(new Error('Room not found')); return Promise.reject(new Error('Room not found'));
} }

View File

@ -13,5 +13,12 @@ export default function permissions(state = initialState.permissions, action) {
}; };
} }
if (action.type === types.ADD_PERMISSIONS) {
return {
...state,
...action.payload
};
}
return state; return state;
} }

View File

@ -3,11 +3,15 @@ import initialState from './initialState';
export default function settings(state = initialState.settings, action) { export default function settings(state = initialState.settings, action) {
if (action.type === types.SET_ALL_SETTINGS) { if (action.type === types.SET_ALL_SETTINGS) {
return {
...action.payload
};
}
if (action.type === types.ADD_SETTINGS) {
return { return {
...state, ...state,
...action.payload ...action.payload
}; };
} }
return state; return state;
} }

View File

@ -5,7 +5,7 @@ const initialState = {
connected: false, connected: false,
errorMessage: '', errorMessage: '',
failure: false, failure: false,
server: '' server: {}
}; };

View File

@ -4,7 +4,7 @@ import * as actions from '../actions';
import { setServer } from '../actions/server'; import { setServer } from '../actions/server';
import { restoreToken } from '../actions/login'; import { restoreToken } from '../actions/login';
import { APP } from '../actions/actionsTypes'; import { APP } from '../actions/actionsTypes';
import realm from '../lib/realm'; import database from '../lib/realm';
import RocketChat from '../lib/rocketchat'; import RocketChat from '../lib/rocketchat';
const restore = function* restore() { const restore = function* restore() {
@ -17,9 +17,9 @@ const restore = function* restore() {
const currentServer = yield call([AsyncStorage, 'getItem'], 'currentServer'); const currentServer = yield call([AsyncStorage, 'getItem'], 'currentServer');
if (currentServer) { if (currentServer) {
yield put(setServer(currentServer)); yield put(setServer(currentServer));
const settings = realm.objects('settings'); const settings = database.objects('settings');
yield put(actions.setAllSettings(RocketChat.parseSettings(settings.slice(0, settings.length)))); yield put(actions.setAllSettings(RocketChat.parseSettings(settings.slice(0, settings.length))));
const permissions = realm.objects('permissions'); const permissions = database.objects('permissions');
yield put(actions.setAllPermissions(RocketChat.parsePermissions(permissions.slice(0, permissions.length)))); yield put(actions.setAllPermissions(RocketChat.parsePermissions(permissions.slice(0, permissions.length))));
} }
yield put(actions.appReady({})); yield put(actions.appReady({}));

View File

@ -2,10 +2,11 @@ import { put, call, takeLatest, race, take } from 'redux-saga/effects';
import { delay } from 'redux-saga'; import { delay } from 'redux-saga';
import { AsyncStorage } from 'react-native'; import { AsyncStorage } from 'react-native';
import { SERVER } from '../actions/actionsTypes'; import { SERVER } from '../actions/actionsTypes';
import * as actions from '../actions';
import { connectRequest, disconnect, disconnect_by_user } from '../actions/connect'; import { connectRequest, disconnect, disconnect_by_user } from '../actions/connect';
import { changedServer, serverSuccess, serverFailure, serverRequest, setServer } from '../actions/server'; import { changedServer, serverSuccess, serverFailure, serverRequest, setServer } from '../actions/server';
import RocketChat from '../lib/rocketchat'; import RocketChat from '../lib/rocketchat';
import realm from '../lib/realm'; import database from '../lib/realm';
import * as NavigationService from '../containers/routes/NavigationService'; import * as NavigationService from '../containers/routes/NavigationService';
const validate = function* validate(server) { const validate = function* validate(server) {
@ -13,10 +14,15 @@ const validate = function* validate(server) {
}; };
const selectServer = function* selectServer({ server }) { const selectServer = function* selectServer({ server }) {
yield database.setActiveDB(server);
yield put(disconnect_by_user()); yield put(disconnect_by_user());
yield put(disconnect()); yield put(disconnect());
yield put(changedServer(server)); yield put(changedServer(server));
yield call([AsyncStorage, 'setItem'], 'currentServer', server); yield call([AsyncStorage, 'setItem'], 'currentServer', server);
const settings = database.objects('settings');
yield put(actions.setAllSettings(RocketChat.parseSettings(settings.slice(0, settings.length))));
const permissions = database.objects('permissions');
yield put(actions.setAllPermissions(RocketChat.parsePermissions(permissions.slice(0, permissions.length))));
yield put(connectRequest(server)); yield put(connectRequest(server));
}; };
@ -39,8 +45,8 @@ const addServer = function* addServer({ server }) {
success: take(SERVER.SUCCESS) success: take(SERVER.SUCCESS)
}); });
if (!error) { if (!error) {
realm.write(() => { database.databases.serversDB.write(() => {
realm.create('servers', { id: server, current: false }, true); database.databases.serversDB.create('servers', { id: server, current: false }, true);
}); });
yield put(setServer(server)); yield put(setServer(server));
} }

View File

@ -6,7 +6,7 @@ import Zeroconf from 'react-native-zeroconf';
import { View, Text, SectionList, StyleSheet, SafeAreaView } from 'react-native'; import { View, Text, SectionList, StyleSheet, SafeAreaView } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { setServer } from '../actions/server'; import { setServer } from '../actions/server';
import realm from '../lib/realm'; import database from '../lib/realm';
import Fade from '../animations/fade'; import Fade from '../animations/fade';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
@ -83,8 +83,9 @@ export default class ListServerView extends React.Component {
this.state = { this.state = {
sections: [] sections: []
}; };
this.data = database.databases.serversDB.objects('servers');
this.redirected = false; this.redirected = false;
realm.addListener('change', this.updateState); this.data.addListener(this.updateState);
} }
componentWillMount() { componentWillMount() {
@ -109,7 +110,7 @@ export default class ListServerView extends React.Component {
componentWillUnmount() { componentWillUnmount() {
zeroconf.stop(); zeroconf.stop();
realm.removeListener('change', this.updateState); this.data.removeAllListeners();
zeroconf.removeListener('update', this.updateState); zeroconf.removeListener('update', this.updateState);
} }
@ -120,7 +121,7 @@ export default class ListServerView extends React.Component {
getState = () => { getState = () => {
const sections = [{ const sections = [{
title: 'My servers', title: 'My servers',
data: realm.objects('servers') data: this.data
}]; }];
this.state.nearBy = zeroconf.getServices(); this.state.nearBy = zeroconf.getServices();

View File

@ -1,15 +1,11 @@
import React from 'react'; import React from 'react';
import Spinner from 'react-native-loading-spinner-overlay'; import Spinner from 'react-native-loading-spinner-overlay';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Keyboard, Text, TextInput, View, ScrollView, TouchableOpacity, SafeAreaView } from 'react-native'; import { Keyboard, Text, TextInput, View, ScrollView, TouchableOpacity, SafeAreaView } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
// import * as actions from '../actions';
import * as loginActions from '../actions/login'; import * as loginActions from '../actions/login';
import KeyboardView from '../presentation/KeyboardView'; import KeyboardView from '../presentation/KeyboardView';
// import { Keyboard } from 'react-native'
import styles from './Styles'; import styles from './Styles';
@ -81,7 +77,6 @@ class LoginView extends React.Component {
return null; return null;
} }
// {this.props.login.isFetching && <Text> LOGANDO</Text>}
render() { render() {
return ( return (
<KeyboardView <KeyboardView
@ -157,7 +152,6 @@ class LoginView extends React.Component {
} }
function mapStateToProps(state) { function mapStateToProps(state) {
// console.log(Object.keys(state));
return { return {
server: state.server.server, server: state.server.server,
Accounts_EmailOrUsernamePlaceholder: state.settings.Accounts_EmailOrUsernamePlaceholder, Accounts_EmailOrUsernamePlaceholder: state.settings.Accounts_EmailOrUsernamePlaceholder,

View File

@ -12,7 +12,7 @@ import styles from './styles';
@connect(state => ({ @connect(state => ({
user: state.login.user, user: state.login.user,
baseUrl: state.settings.Site_Url, baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
activeUsers: state.activeUsers activeUsers: state.activeUsers
})) }))
export default class extends React.Component { export default class extends React.Component {

View File

@ -8,7 +8,7 @@ import { bindActionCreators } from 'redux';
import * as actions from '../../actions'; import * as actions from '../../actions';
import { openRoom } from '../../actions/room'; import { openRoom } from '../../actions/room';
import { editCancel } from '../../actions/messages'; import { editCancel } from '../../actions/messages';
import realm from '../../lib/realm'; import database from '../../lib/realm';
import RocketChat from '../../lib/rocketchat'; import RocketChat from '../../lib/rocketchat';
import Message from '../../containers/message'; import Message from '../../containers/message';
import MessageActions from '../../containers/MessageActions'; import MessageActions from '../../containers/MessageActions';
@ -25,8 +25,7 @@ const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1._id !== r2._i
const typing = () => <Typing />; const typing = () => <Typing />;
@connect( @connect(
state => ({ state => ({
server: state.server.server, Site_Url: state.settings.Site_Url || state.server ? state.server.server : '',
Site_Url: state.settings.Site_Url,
Message_TimeFormat: state.settings.Message_TimeFormat, Message_TimeFormat: state.settings.Message_TimeFormat,
loading: state.messages.isFetching, loading: state.messages.isFetching,
user: state.login.user user: state.login.user
@ -44,7 +43,6 @@ export default class RoomView extends React.Component {
user: PropTypes.object.isRequired, user: PropTypes.object.isRequired,
editCancel: PropTypes.func, editCancel: PropTypes.func,
rid: PropTypes.string, rid: PropTypes.string,
server: PropTypes.string,
name: PropTypes.string, name: PropTypes.string,
Site_Url: PropTypes.string, Site_Url: PropTypes.string,
Message_TimeFormat: PropTypes.string, Message_TimeFormat: PropTypes.string,
@ -64,11 +62,10 @@ export default class RoomView extends React.Component {
this.props.navigation.state.params.name || this.props.navigation.state.params.name ||
this.props.navigation.state.params.room.name; this.props.navigation.state.params.room.name;
this.data = realm this.data = database.objects('messages')
.objects('messages') .filtered('rid = $0', this.rid)
.filtered('_server.id = $0 AND rid = $1', this.props.server, this.rid)
.sorted('ts', true); .sorted('ts', true);
this.room = realm.objects('subscriptions').filtered('rid = $0', this.rid); this.room = database.objects('subscriptions').filtered('rid = $0', this.rid);
this.state = { this.state = {
dataSource: ds.cloneWithRows([]), dataSource: ds.cloneWithRows([]),
loaded: true, loaded: true,

View File

@ -16,7 +16,7 @@ import styles from './styles';
@connect(state => ({ @connect(state => ({
user: state.login.user, user: state.login.user,
connected: state.meteor.connected, connected: state.meteor.connected,
baseUrl: state.settings.Site_Url baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
}), dispatch => ({ }), dispatch => ({
setSearch: searchText => dispatch(setSearch(searchText)) setSearch: searchText => dispatch(setSearch(searchText))
})) }))

View File

@ -7,7 +7,7 @@ import { Platform, View, TextInput, SafeAreaView } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import * as actions from '../../actions'; import * as actions from '../../actions';
import * as server from '../../actions/connect'; import * as server from '../../actions/connect';
import realm from '../../lib/realm'; import database from '../../lib/realm';
import RocketChat from '../../lib/rocketchat'; import RocketChat from '../../lib/rocketchat';
import RoomItem from '../../presentation/RoomItem'; import RoomItem from '../../presentation/RoomItem';
import Banner from '../../containers/Banner'; import Banner from '../../containers/Banner';
@ -47,7 +47,7 @@ export default class RoomsListView extends React.Component {
dataSource: ds.cloneWithRows([]), dataSource: ds.cloneWithRows([]),
searchText: '' searchText: ''
}; };
this.data = realm.objects('subscriptions').filtered('_server.id = $0', this.props.server).sorted('roomUpdatedAt', true); this.data = database.objects('subscriptions').sorted('roomUpdatedAt', true);
} }
componentDidMount() { componentDidMount() {
@ -63,7 +63,7 @@ export default class RoomsListView extends React.Component {
componentWillReceiveProps(props) { componentWillReceiveProps(props) {
if (this.props.server !== props.server) { if (this.props.server !== props.server) {
this.data.removeListener(this.updateState); this.data.removeListener(this.updateState);
this.data = realm.objects('subscriptions').filtered('_server.id = $0', props.server).sorted('roomUpdatedAt', true); this.data = database.objects('subscriptions').sorted('roomUpdatedAt', true);
this.data.addListener(this.updateState); this.data.addListener(this.updateState);
} else if (this.props.searchText !== props.searchText) { } else if (this.props.searchText !== props.searchText) {
this.search(props.searchText); this.search(props.searchText);
@ -151,7 +151,8 @@ export default class RoomsListView extends React.Component {
if (item.t === 'd') { if (item.t === 'd') {
RocketChat.createDirectMessage(item.username) RocketChat.createDirectMessage(item.username)
.then(room => new Promise((resolve) => { .then(room => new Promise((resolve) => {
const data = realm.objects('subscriptions').filtered('_server.id = $0 AND rid = $1', this.props.server, room.rid); const data = database.objects('subscriptions')
.filtered('rid = $1', room.rid);
if (data.length) { if (data.length) {
return resolve(data[0]); return resolve(data[0]);

View File

@ -8,7 +8,7 @@ import { connect } from 'react-redux';
import * as actions from '../actions'; import * as actions from '../actions';
import * as server from '../actions/connect'; import * as server from '../actions/connect';
import * as createChannelActions from '../actions/createChannel'; import * as createChannelActions from '../actions/createChannel';
import realm from '../lib/realm'; import database from '../lib/realm';
import RocketChat from '../lib/rocketchat'; import RocketChat from '../lib/rocketchat';
import RoomItem from '../presentation/RoomItem'; import RoomItem from '../presentation/RoomItem';
import Banner from '../containers/Banner'; import Banner from '../containers/Banner';
@ -57,7 +57,6 @@ const styles = StyleSheet.create({
const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
@connect( @connect(
state => ({ state => ({
server: state.server.server,
login: state.login, login: state.login,
Site_Url: state.settings.Site_Url, Site_Url: state.settings.Site_Url,
users: state.createChannel.users users: state.createChannel.users
@ -74,7 +73,6 @@ export default class RoomsListView extends React.Component {
static propTypes = { static propTypes = {
navigation: PropTypes.object.isRequired, navigation: PropTypes.object.isRequired,
Site_Url: PropTypes.string, Site_Url: PropTypes.string,
server: PropTypes.string,
addUser: PropTypes.func.isRequired, addUser: PropTypes.func.isRequired,
removeUser: PropTypes.func.isRequired, removeUser: PropTypes.func.isRequired,
resetCreateChannel: PropTypes.func.isRequired, resetCreateChannel: PropTypes.func.isRequired,
@ -83,15 +81,12 @@ export default class RoomsListView extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.data = realm this.data = database
.objects('subscriptions') .objects('subscriptions')
.filtered('_server.id = $0 AND t = $1', this.props.server, 'd'); .filtered('t = $0', 'd');
this.state = { this.state = {
dataSource: ds.cloneWithRows(this.data), dataSource: ds.cloneWithRows(this.data),
// searching: false,
// searchDataSource: [],
searchText: '' searchText: ''
// login: false
}; };
this.data.addListener(this.updateState); this.data.addListener(this.updateState);
} }
@ -105,7 +100,6 @@ export default class RoomsListView extends React.Component {
const searchText = text.trim(); const searchText = text.trim();
this.setState({ this.setState({
searchText: text searchText: text
// searching: searchText !== ''
}); });
if (searchText === '') { if (searchText === '') {
return this.setState({ return this.setState({

View File

@ -21,7 +21,7 @@
] ]
}, },
"dependencies": { "dependencies": {
"@storybook/addons": "^3.2.18", "@storybook/addons": "^3.3.1",
"@storybook/react-native": "^3.2.18", "@storybook/react-native": "^3.2.18",
"babel-plugin-transform-decorators-legacy": "^1.3.4", "babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-remove-console": "^6.8.5", "babel-plugin-transform-remove-console": "^6.8.5",