Skip to content

Commit

Permalink
[FIX] Add Realm.safeAddListener (#785)
Browse files Browse the repository at this point in the history
  • Loading branch information
diegolmello committed Apr 4, 2019
1 parent b23ff03 commit 3a4a619
Show file tree
Hide file tree
Showing 14 changed files with 52 additions and 34 deletions.
6 changes: 3 additions & 3 deletions app/containers/EmojiPicker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import TabBar from './TabBar';
import EmojiCategory from './EmojiCategory';
import styles from './styles';
import categories from './categories';
import database from '../../lib/realm';
import database, { safeAddListener } from '../../lib/realm';
import { emojisByCategory } from '../../emojis';
import protectedFunction from '../../lib/methods/helpers/protectedFunction';

Expand Down Expand Up @@ -45,8 +45,8 @@ export default class EmojiPicker extends Component {
this.updateFrequentlyUsed();
this.updateCustomEmojis();
requestAnimationFrame(() => this.setState({ show: true }));
this.frequentlyUsed.addListener(this.updateFrequentlyUsed);
this.customEmojis.addListener(this.updateCustomEmojis);
safeAddListener(this.frequentlyUsed, this.updateFrequentlyUsed);
safeAddListener(this.customEmojis, this.updateCustomEmojis);
}

shouldComponentUpdate(nextProps, nextState) {
Expand Down
20 changes: 19 additions & 1 deletion app/lib/realm.js
Original file line number Diff line number Diff line change
Expand Up @@ -346,4 +346,22 @@ class DB {
});
}
}
export default new DB();
const db = new DB();
export default db;

// Realm workaround for "Cannot create asynchronous query while in a write transaction"
// inpired from https://github.com/realm/realm-js/issues/1188#issuecomment-359223918
export function safeAddListener(results, callback, database = db) {
if (!results || !results.addListener) {
console.log('⚠️ safeAddListener called for non addListener-compliant object');
return;
}

if (database.isInTransaction) {
setTimeout(() => {
safeAddListener(results, callback);
}, 50);
} else {
results.addListener(callback);
}
}
4 changes: 2 additions & 2 deletions app/lib/rocketchat.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Rocketchat as RocketchatClient } from '@rocket.chat/sdk';
import reduxStore from './createStore';
import defaultSettings from '../constants/settings';
import messagesStatus from '../constants/messagesStatus';
import database from './realm';
import database, { safeAddListener } from './realm';
import log from '../utils/log';
import { isIOS, getBundleId } from '../utils/deviceInfo';

Expand Down Expand Up @@ -65,7 +65,7 @@ const RocketChat = {
if (data.length) {
return resolve(data[0]);
}
data.addListener(() => {
safeAddListener(data, () => {
if (!data.length) { return; }
data.removeAllListeners();
resolve(data[0]);
Expand Down
4 changes: 2 additions & 2 deletions app/views/NewMessageView.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { connect } from 'react-redux';
import { SafeAreaView } from 'react-navigation';
import equal from 'deep-equal';

import database from '../lib/realm';
import database, { safeAddListener } from '../lib/realm';
import RocketChat from '../lib/rocketchat';
import UserItem from '../presentation/UserItem';
import debounce from '../utils/debounce';
Expand Down Expand Up @@ -79,7 +79,7 @@ export default class NewMessageView extends LoggedView {
this.state = {
search: []
};
this.data.addListener(this.updateState);
safeAddListener(this.data, this.updateState);
}

shouldComponentUpdate(nextProps, nextState) {
Expand Down
4 changes: 2 additions & 2 deletions app/views/RoomActionsView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import sharedStyles from '../Styles';
import Avatar from '../../containers/Avatar';
import Status from '../../containers/Status';
import Touch from '../../utils/touch';
import database from '../../lib/realm';
import database, { safeAddListener } from '../../lib/realm';
import RocketChat from '../../lib/rocketchat';
import log from '../../utils/log';
import RoomTypeIcon from '../../containers/RoomTypeIcon';
Expand Down Expand Up @@ -81,7 +81,7 @@ export default class RoomActionsView extends LoggedView {
} else if (room.t === 'd') {
this.updateRoomMember();
}
this.rooms.addListener(this.updateRoom);
safeAddListener(this.rooms, this.updateRoom);
}

shouldComponentUpdate(nextProps, nextState) {
Expand Down
4 changes: 2 additions & 2 deletions app/views/RoomInfoEditView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import sharedStyles from '../Styles';
import styles from './styles';
import scrollPersistTaps from '../../utils/scrollPersistTaps';
import { showErrorAlert, showToast } from '../../utils/info';
import database from '../../lib/realm';
import database, { safeAddListener } from '../../lib/realm';
import RocketChat from '../../lib/rocketchat';
import RCTextInput from '../../containers/TextInput';
import Loading from '../../containers/Loading';
Expand Down Expand Up @@ -77,7 +77,7 @@ export default class RoomInfoEditView extends LoggedView {
componentDidMount() {
this.updateRoom();
this.init();
this.rooms.addListener(this.updateRoom);
safeAddListener(this.rooms, this.updateRoom);
const { room } = this.state;
this.permissions = RocketChat.hasPermission(PERMISSIONS_ARRAY, room.rid);
}
Expand Down
4 changes: 2 additions & 2 deletions app/views/RoomInfoView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Status from '../../containers/Status';
import Avatar from '../../containers/Avatar';
import styles from './styles';
import sharedStyles from '../Styles';
import database from '../../lib/realm';
import database, { safeAddListener } from '../../lib/realm';
import RocketChat from '../../lib/rocketchat';
import log from '../../utils/log';
import RoomTypeIcon from '../../containers/RoomTypeIcon';
Expand Down Expand Up @@ -87,7 +87,7 @@ export default class RoomInfoView extends LoggedView {
}

async componentDidMount() {
this.rooms.addListener(this.updateRoom);
safeAddListener(this.rooms, this.updateRoom);
const { room } = this.state;
const permissions = RocketChat.hasPermission([PERMISSION_EDIT_ROOM], room.rid);
if (permissions[PERMISSION_EDIT_ROOM]) {
Expand Down
4 changes: 2 additions & 2 deletions app/views/RoomMembersView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import styles from './styles';
import UserItem from '../../presentation/UserItem';
import scrollPersistTaps from '../../utils/scrollPersistTaps';
import RocketChat from '../../lib/rocketchat';
import database from '../../lib/realm';
import database, { safeAddListener } from '../../lib/realm';
import { showToast } from '../../utils/info';
import log from '../../utils/log';
import { vibrate } from '../../utils/vibration';
Expand Down Expand Up @@ -81,7 +81,7 @@ export default class RoomMembersView extends LoggedView {

componentDidMount() {
this.fetchMembers();
this.rooms.addListener(this.updateRoom);
safeAddListener(this.rooms, this.updateRoom);

const { navigation } = this.props;
navigation.setParams({ toggleStatus: this.toggleStatus });
Expand Down
4 changes: 2 additions & 2 deletions app/views/RoomView/List.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import { responsive } from 'react-native-responsive-ui';

import styles from './styles';
import database from '../../lib/realm';
import database, { safeAddListener } from '../../lib/realm';
import scrollPersistTaps from '../../utils/scrollPersistTaps';
import debounce from '../../utils/debounce';
import RocketChat from '../../lib/rocketchat';
Expand Down Expand Up @@ -36,7 +36,7 @@ export class List extends React.Component {
messages: this.data.slice(),
showScollToBottomButton: false
};
this.data.addListener(this.updateState);
safeAddListener(this.data, this.updateState);
}

// shouldComponentUpdate(nextProps, nextState) {
Expand Down
4 changes: 2 additions & 2 deletions app/views/RoomView/UploadProgress.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import PropTypes from 'prop-types';
import { responsive } from 'react-native-responsive-ui';
import equal from 'deep-equal';

import database from '../../lib/realm';
import database, { safeAddListener } from '../../lib/realm';
import RocketChat from '../../lib/rocketchat';
import log from '../../utils/log';
import I18n from '../../i18n';
Expand Down Expand Up @@ -74,7 +74,7 @@ export default class UploadProgress extends Component {
};
const { rid } = this.props;
this.uploads = database.objects('uploads').filtered('rid = $0', rid);
this.uploads.addListener(this.updateUploads);
safeAddListener(this.uploads, this.updateUploads);
}

componentDidMount() {
Expand Down
4 changes: 2 additions & 2 deletions app/views/RoomView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { openRoom as openRoomAction, closeRoom as closeRoomAction } from '../../
import { toggleReactionPicker as toggleReactionPickerAction, actionsShow as actionsShowAction } from '../../actions/messages';
import LoggedView from '../View';
import { List } from './List';
import database from '../../lib/realm';
import database, { safeAddListener } from '../../lib/realm';
import RocketChat from '../../lib/rocketchat';
import Message from '../../containers/message';
import MessageActions from '../../containers/MessageActions';
Expand Down Expand Up @@ -114,7 +114,7 @@ export default class RoomView extends LoggedView {
() => this.updateRoom()
);
}
this.rooms.addListener(this.updateRoom);
safeAddListener(this.rooms, this.updateRoom);
this.internalSetState({ loaded: true });
}

Expand Down
4 changes: 2 additions & 2 deletions app/views/RoomsListView/ServerDropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { toggleServerDropdown as toggleServerDropdownAction } from '../../action
import { selectServerRequest as selectServerRequestAction } from '../../actions/server';
import { appStart as appStartAction } from '../../actions';
import styles from './styles';
import database from '../../lib/realm';
import database, { safeAddListener } from '../../lib/realm';
import Touch from '../../utils/touch';
import RocketChat from '../../lib/rocketchat';
import I18n from '../../i18n';
Expand Down Expand Up @@ -46,7 +46,7 @@ class ServerDropdown extends Component {
servers: this.servers
};
this.animatedValue = new Animated.Value(0);
this.servers.addListener(this.updateState);
safeAddListener(this.servers, this.updateState);
}

componentDidMount() {
Expand Down
16 changes: 8 additions & 8 deletions app/views/RoomsListView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Orientation from 'react-native-orientation-locker';

import SearchBox from '../../containers/SearchBox';
import ConnectionBadge from '../../containers/ConnectionBadge';
import database from '../../lib/realm';
import database, { safeAddListener } from '../../lib/realm';
import RocketChat from '../../lib/rocketchat';
import RoomItem, { ROW_HEIGHT } from '../../presentation/RoomItem';
import styles from './styles';
Expand Down Expand Up @@ -277,15 +277,15 @@ export default class RoomsListView extends LoggedView {
if (showUnread) {
this.unread = this.data.filtered('archived != true && open == true').filtered('(unread > 0 || alert == true)');
unread = this.removeRealmInstance(this.unread);
this.unread.addListener(debounce(() => this.internalSetState({ unread: this.removeRealmInstance(this.unread) }), 300));
safeAddListener(this.unread, debounce(() => this.internalSetState({ unread: this.removeRealmInstance(this.unread) }), 300));
} else {
this.removeListener(unread);
}
// favorites
if (showFavorites) {
this.favorites = this.data.filtered('f == true');
favorites = this.removeRealmInstance(this.favorites);
this.favorites.addListener(debounce(() => this.internalSetState({ favorites: this.removeRealmInstance(this.favorites) }), 300));
safeAddListener(this.favorites, debounce(() => this.internalSetState({ favorites: this.removeRealmInstance(this.favorites) }), 300));
} else {
this.removeListener(favorites);
}
Expand All @@ -307,10 +307,10 @@ export default class RoomsListView extends LoggedView {
this.livechat = this.data.filtered('t == $0', 'l');
livechat = this.removeRealmInstance(this.livechat);

this.channels.addListener(debounce(() => this.internalSetState({ channels: this.removeRealmInstance(this.channels) }), 300));
this.privateGroup.addListener(debounce(() => this.internalSetState({ privateGroup: this.removeRealmInstance(this.privateGroup) }), 300));
this.direct.addListener(debounce(() => this.internalSetState({ direct: this.removeRealmInstance(this.direct) }), 300));
this.livechat.addListener(debounce(() => this.internalSetState({ livechat: this.removeRealmInstance(this.livechat) }), 300));
safeAddListener(this.channels, debounce(() => this.internalSetState({ channels: this.removeRealmInstance(this.channels) }), 300));
safeAddListener(this.privateGroup, debounce(() => this.internalSetState({ privateGroup: this.removeRealmInstance(this.privateGroup) }), 300));
safeAddListener(this.direct, debounce(() => this.internalSetState({ direct: this.removeRealmInstance(this.direct) }), 300));
safeAddListener(this.livechat, debounce(() => this.internalSetState({ livechat: this.removeRealmInstance(this.livechat) }), 300));
this.removeListener(this.chats);
} else {
// chats
Expand All @@ -321,7 +321,7 @@ export default class RoomsListView extends LoggedView {
}
chats = this.removeRealmInstance(this.chats);

this.chats.addListener(debounce(() => this.internalSetState({ chats: this.removeRealmInstance(this.chats) }), 300));
safeAddListener(this.chats, debounce(() => this.internalSetState({ chats: this.removeRealmInstance(this.chats) }), 300));
this.removeListener(this.channels);
this.removeListener(this.privateGroup);
this.removeListener(this.direct);
Expand Down
4 changes: 2 additions & 2 deletions app/views/SelectedUsersView.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import equal from 'deep-equal';
import {
addUser as addUserAction, removeUser as removeUserAction, reset as resetAction, setLoading as setLoadingAction
} from '../actions/selectedUsers';
import database from '../lib/realm';
import database, { safeAddListener } from '../lib/realm';
import RocketChat from '../lib/rocketchat';
import UserItem from '../presentation/UserItem';
import Loading from '../containers/Loading';
Expand Down Expand Up @@ -88,7 +88,7 @@ export default class SelectedUsersView extends LoggedView {
this.state = {
search: []
};
this.data.addListener(this.updateState);
safeAddListener(this.data, this.updateState);
}

componentDidMount() {
Expand Down

0 comments on commit 3a4a619

Please sign in to comment.