verdnatura-chat/app/lib/realm.js

459 lines
12 KiB
JavaScript
Raw Normal View History

2017-08-03 18:23:43 +00:00
import Realm from 'realm';
// import { AsyncStorage } from 'react-native';
// Realm.clearTestState();
// AsyncStorage.clear();
2017-08-03 18:23:43 +00:00
const serversSchema = {
name: 'servers',
primaryKey: 'id',
properties: {
id: 'string',
name: { type: 'string', optional: true },
2019-02-27 20:29:37 +00:00
iconURL: { type: 'string', optional: true },
2019-04-17 17:01:03 +00:00
roomsUpdatedAt: { type: 'date', optional: true },
version: 'string?'
2017-08-03 18:23:43 +00:00
}
};
const settingsSchema = {
name: 'settings',
primaryKey: '_id',
properties: {
_id: 'string',
valueAsString: { type: 'string', optional: true },
valueAsBoolean: { type: 'bool', optional: true },
2017-11-19 04:10:29 +00:00
valueAsNumber: { type: 'int', optional: true },
_updatedAt: { type: 'date', optional: true }
2017-08-03 18:23:43 +00:00
}
};
2017-11-24 20:44:52 +00:00
const permissionsSchema = {
name: 'permissions',
primaryKey: '_id',
properties: {
_id: 'string',
2019-04-26 20:54:58 +00:00
roles: 'string[]',
2017-11-24 20:44:52 +00:00
_updatedAt: { type: 'date', optional: true }
}
};
2017-11-08 20:23:46 +00:00
const roomsSchema = {
name: 'rooms',
primaryKey: '_id',
properties: {
_id: 'string',
name: 'string?',
broadcast: { type: 'bool', optional: true }
2017-11-08 20:23:46 +00:00
}
};
2017-08-03 18:23:43 +00:00
const subscriptionSchema = {
name: 'subscriptions',
primaryKey: '_id',
properties: {
_id: 'string',
f: { type: 'bool', optional: true },
2017-08-03 18:23:43 +00:00
t: 'string',
2017-08-07 00:34:35 +00:00
ts: { type: 'date', optional: true },
ls: { type: 'date', optional: true },
name: { type: 'string', indexed: true },
2017-08-05 18:16:32 +00:00
fname: { type: 'string', optional: true },
rid: { type: 'string', indexed: true },
2017-08-07 00:34:35 +00:00
open: { type: 'bool', optional: true },
alert: { type: 'bool', optional: true },
2019-04-26 20:54:58 +00:00
roles: 'string[]',
2017-08-11 18:18:09 +00:00
unread: { type: 'int', optional: true },
userMentions: { type: 'int', optional: true },
roomUpdatedAt: { type: 'date', optional: true },
ro: { type: 'bool', optional: true },
lastOpen: { type: 'date', optional: true },
lastMessage: { type: 'messages', optional: true },
description: { type: 'string', optional: true },
announcement: { type: 'string', optional: true },
topic: { type: 'string', optional: true },
blocked: { type: 'bool', optional: true },
blocker: { type: 'bool', optional: true },
reactWhenReadOnly: { type: 'bool', optional: true },
archived: { type: 'bool', optional: true },
Beta (#265) * Fabric iOS * Fabric configured on iOS and Android * - react-native-fabric configured - login tracked * README updated * Run scripts from README updated * README scripts * get rooms and messages by rest * user status * more improves * more improves * send pong on timeout * fix some methods * more tests * rest messages * Room actions (#266) * Toggle notifications * Search messages * Invite users * Mute/Unmute users in room * rocket.cat messages * Room topic layout fixed * Starred messages loading onEndReached * Room actions onEndReached * Unnecessary login request * Login loading * Login services fixed * User presence layout * ïmproves on room actions view * Removed unnecessary data from SelectedUsersView * load few messages on open room, search message improve * fix loading messages forever * Removed state from search * Custom message time format * secureTextEntry layout * Reduce android app size * Roles subscription fix * Public routes navigation * fix reconnect * - New login/register, login, register * proguard * Login flux * App init/restore * Android layout fixes * Multiple meteor connection requests fixed * Nested attachments * Nested attachments * fix check status * New login layout (#269) * Public routes navigation * New login/register, login, register * Multiple meteor connection requests fixed * Nested attachments * Button component * TextInput android layout fixed * Register fixed * Thinner close modal button * Requests /me after login only one time * Static images moved * fix reconnect * fix ddp * fix custom emoji * New message layout (#273) * Grouping messages * Message layout * Users typing animation * Image attachment layout
2018-04-24 19:34:03 +00:00
joinCodeRequired: { type: 'bool', optional: true },
notifications: { type: 'bool', optional: true },
muted: 'string[]',
2019-04-01 14:45:17 +00:00
broadcast: { type: 'bool', optional: true },
2019-04-08 12:35:28 +00:00
prid: { type: 'string', optional: true },
draftMessage: { type: 'string', optional: true },
lastThreadSync: 'date?'
2017-08-03 18:23:43 +00:00
}
};
2017-08-04 00:34:37 +00:00
const usersSchema = {
name: 'users',
primaryKey: '_id',
2017-08-04 00:34:37 +00:00
properties: {
_id: 'string',
2017-08-04 00:34:37 +00:00
username: 'string',
name: { type: 'string', optional: true }
2017-08-04 00:34:37 +00:00
}
2017-08-05 18:16:32 +00:00
};
2017-08-04 00:34:37 +00:00
const attachmentFields = {
name: 'attachmentFields',
properties: {
title: { type: 'string', optional: true },
value: { type: 'string', optional: true },
short: { type: 'bool', optional: true }
}
};
const attachment = {
name: 'attachment',
properties: {
description: { type: 'string', optional: true },
image_size: { type: 'int', optional: true },
image_type: { type: 'string', optional: true },
image_url: { type: 'string', optional: true },
audio_size: { type: 'int', optional: true },
audio_type: { type: 'string', optional: true },
audio_url: { type: 'string', optional: true },
video_size: { type: 'int', optional: true },
video_type: { type: 'string', optional: true },
video_url: { type: 'string', optional: true },
title: { type: 'string', optional: true },
title_link: { type: 'string', optional: true },
// title_link_download: { type: 'bool', optional: true },
type: { type: 'string', optional: true },
author_icon: { type: 'string', optional: true },
author_name: { type: 'string', optional: true },
author_link: { type: 'string', optional: true },
text: { type: 'string', optional: true },
color: { type: 'string', optional: true },
ts: { type: 'date', optional: true },
attachments: { type: 'list', objectType: 'attachment' },
Beta (#265) * Fabric iOS * Fabric configured on iOS and Android * - react-native-fabric configured - login tracked * README updated * Run scripts from README updated * README scripts * get rooms and messages by rest * user status * more improves * more improves * send pong on timeout * fix some methods * more tests * rest messages * Room actions (#266) * Toggle notifications * Search messages * Invite users * Mute/Unmute users in room * rocket.cat messages * Room topic layout fixed * Starred messages loading onEndReached * Room actions onEndReached * Unnecessary login request * Login loading * Login services fixed * User presence layout * ïmproves on room actions view * Removed unnecessary data from SelectedUsersView * load few messages on open room, search message improve * fix loading messages forever * Removed state from search * Custom message time format * secureTextEntry layout * Reduce android app size * Roles subscription fix * Public routes navigation * fix reconnect * - New login/register, login, register * proguard * Login flux * App init/restore * Android layout fixes * Multiple meteor connection requests fixed * Nested attachments * Nested attachments * fix check status * New login layout (#269) * Public routes navigation * New login/register, login, register * Multiple meteor connection requests fixed * Nested attachments * Button component * TextInput android layout fixed * Register fixed * Thinner close modal button * Requests /me after login only one time * Static images moved * fix reconnect * fix ddp * fix custom emoji * New message layout (#273) * Grouping messages * Message layout * Users typing animation * Image attachment layout
2018-04-24 19:34:03 +00:00
fields: {
type: 'list', objectType: 'attachmentFields', default: []
}
}
};
const url = {
name: 'url',
primaryKey: 'url',
properties: {
// _id: { type: 'int', optional: true },
url: { type: 'string', optional: true },
title: { type: 'string', optional: true },
description: { type: 'string', optional: true },
image: { type: 'string', optional: true }
}
};
const messagesReactionsSchema = {
name: 'messagesReactions',
primaryKey: '_id',
properties: {
_id: 'string',
emoji: 'string',
usernames: 'string[]'
}
};
const messagesEditedBySchema = {
name: 'messagesEditedBy',
primaryKey: '_id',
properties: {
_id: { type: 'string', optional: true },
username: { type: 'string', optional: true }
}
};
2017-08-04 00:34:37 +00:00
const messagesSchema = {
name: 'messages',
primaryKey: '_id',
properties: {
_id: 'string',
2017-08-05 18:16:32 +00:00
msg: { type: 'string', optional: true },
t: { type: 'string', optional: true },
rid: { type: 'string', indexed: true },
2017-08-04 00:34:37 +00:00
ts: 'date',
u: 'users',
2017-08-13 23:45:47 +00:00
alias: { type: 'string', optional: true },
parseUrls: { type: 'bool', optional: true },
groupable: { type: 'bool', optional: true },
avatar: { type: 'string', optional: true },
attachments: { type: 'list', objectType: 'attachment' },
urls: { type: 'list', objectType: 'url', default: [] },
2017-08-09 20:08:50 +00:00
_updatedAt: { type: 'date', optional: true },
status: { type: 'int', optional: true },
pinned: { type: 'bool', optional: true },
starred: { type: 'bool', optional: true },
editedBy: 'messagesEditedBy',
reactions: { type: 'list', objectType: 'messagesReactions' },
2019-04-08 12:35:28 +00:00
role: { type: 'string', optional: true },
drid: { type: 'string', optional: true },
dcount: { type: 'int', optional: true },
2019-04-17 17:01:03 +00:00
dlm: { type: 'date', optional: true },
tmid: { type: 'string', optional: true },
tcount: { type: 'int', optional: true },
tlm: { type: 'date', optional: true },
replies: 'string[]',
mentions: { type: 'list', objectType: 'users' },
channels: { type: 'list', objectType: 'rooms' }
2019-04-17 17:01:03 +00:00
}
};
const threadsSchema = {
name: 'threads',
primaryKey: '_id',
properties: {
_id: 'string',
msg: { type: 'string', optional: true },
t: { type: 'string', optional: true },
rid: { type: 'string', indexed: true },
ts: 'date',
u: 'users',
alias: { type: 'string', optional: true },
parseUrls: { type: 'bool', optional: true },
groupable: { type: 'bool', optional: true },
avatar: { type: 'string', optional: true },
attachments: { type: 'list', objectType: 'attachment' },
urls: { type: 'list', objectType: 'url', default: [] },
_updatedAt: { type: 'date', optional: true },
status: { type: 'int', optional: true },
pinned: { type: 'bool', optional: true },
starred: { type: 'bool', optional: true },
editedBy: 'messagesEditedBy',
reactions: { type: 'list', objectType: 'messagesReactions' },
role: { type: 'string', optional: true },
drid: { type: 'string', optional: true },
dcount: { type: 'int', optional: true },
dlm: { type: 'date', optional: true },
tmid: { type: 'string', optional: true },
tcount: { type: 'int', optional: true },
tlm: { type: 'date', optional: true },
replies: 'string[]',
draftMessage: 'string?'
2019-04-17 17:01:03 +00:00
}
};
const threadMessagesSchema = {
name: 'threadMessages',
primaryKey: '_id',
properties: {
_id: 'string',
msg: { type: 'string', optional: true },
t: { type: 'string', optional: true },
rid: { type: 'string', indexed: true },
ts: 'date',
u: 'users',
alias: { type: 'string', optional: true },
parseUrls: { type: 'bool', optional: true },
groupable: { type: 'bool', optional: true },
avatar: { type: 'string', optional: true },
attachments: { type: 'list', objectType: 'attachment' },
urls: { type: 'list', objectType: 'url', default: [] },
_updatedAt: { type: 'date', optional: true },
status: { type: 'int', optional: true },
pinned: { type: 'bool', optional: true },
starred: { type: 'bool', optional: true },
editedBy: 'messagesEditedBy',
reactions: { type: 'list', objectType: 'messagesReactions' },
role: { type: 'string', optional: true }
2017-08-04 00:34:37 +00:00
}
};
const frequentlyUsedEmojiSchema = {
name: 'frequentlyUsedEmoji',
primaryKey: 'content',
properties: {
content: { type: 'string', optional: true },
extension: { type: 'string', optional: true },
isCustom: 'bool',
count: 'int'
}
};
const customEmojisSchema = {
name: 'customEmojis',
primaryKey: '_id',
properties: {
_id: 'string',
name: 'string',
aliases: 'string[]',
extension: 'string',
_updatedAt: { type: 'date', optional: true }
}
};
const rolesSchema = {
name: 'roles',
primaryKey: '_id',
properties: {
_id: 'string',
description: { type: 'string', optional: true }
}
};
const uploadsSchema = {
name: 'uploads',
primaryKey: 'path',
properties: {
path: 'string',
rid: 'string',
name: { type: 'string', optional: true },
description: { type: 'string', optional: true },
size: { type: 'int', optional: true },
type: { type: 'string', optional: true },
store: { type: 'string', optional: true },
progress: { type: 'int', default: 1 },
error: { type: 'bool', default: false }
}
};
2019-04-08 12:35:28 +00:00
const usersTypingSchema = {
name: 'usersTyping',
properties: {
rid: { type: 'string', indexed: true },
username: { type: 'string', optional: true }
}
};
2019-04-29 16:03:52 +00:00
const activeUsersSchema = {
name: 'activeUsers',
primaryKey: 'id',
properties: {
id: 'string',
name: 'string?',
username: 'string?',
status: 'string?',
utcOffset: 'double?'
}
};
const schema = [
settingsSchema,
subscriptionSchema,
messagesSchema,
2019-04-17 17:01:03 +00:00
threadsSchema,
threadMessagesSchema,
usersSchema,
roomsSchema,
attachment,
attachmentFields,
messagesEditedBySchema,
permissionsSchema,
url,
frequentlyUsedEmojiSchema,
customEmojisSchema,
messagesReactionsSchema,
Beta (#265) * Fabric iOS * Fabric configured on iOS and Android * - react-native-fabric configured - login tracked * README updated * Run scripts from README updated * README scripts * get rooms and messages by rest * user status * more improves * more improves * send pong on timeout * fix some methods * more tests * rest messages * Room actions (#266) * Toggle notifications * Search messages * Invite users * Mute/Unmute users in room * rocket.cat messages * Room topic layout fixed * Starred messages loading onEndReached * Room actions onEndReached * Unnecessary login request * Login loading * Login services fixed * User presence layout * ïmproves on room actions view * Removed unnecessary data from SelectedUsersView * load few messages on open room, search message improve * fix loading messages forever * Removed state from search * Custom message time format * secureTextEntry layout * Reduce android app size * Roles subscription fix * Public routes navigation * fix reconnect * - New login/register, login, register * proguard * Login flux * App init/restore * Android layout fixes * Multiple meteor connection requests fixed * Nested attachments * Nested attachments * fix check status * New login layout (#269) * Public routes navigation * New login/register, login, register * Multiple meteor connection requests fixed * Nested attachments * Button component * TextInput android layout fixed * Register fixed * Thinner close modal button * Requests /me after login only one time * Static images moved * fix reconnect * fix ddp * fix custom emoji * New message layout (#273) * Grouping messages * Message layout * Users typing animation * Image attachment layout
2018-04-24 19:34:03 +00:00
rolesSchema,
uploadsSchema
];
Beta (#265) * Fabric iOS * Fabric configured on iOS and Android * - react-native-fabric configured - login tracked * README updated * Run scripts from README updated * README scripts * get rooms and messages by rest * user status * more improves * more improves * send pong on timeout * fix some methods * more tests * rest messages * Room actions (#266) * Toggle notifications * Search messages * Invite users * Mute/Unmute users in room * rocket.cat messages * Room topic layout fixed * Starred messages loading onEndReached * Room actions onEndReached * Unnecessary login request * Login loading * Login services fixed * User presence layout * ïmproves on room actions view * Removed unnecessary data from SelectedUsersView * load few messages on open room, search message improve * fix loading messages forever * Removed state from search * Custom message time format * secureTextEntry layout * Reduce android app size * Roles subscription fix * Public routes navigation * fix reconnect * - New login/register, login, register * proguard * Login flux * App init/restore * Android layout fixes * Multiple meteor connection requests fixed * Nested attachments * Nested attachments * fix check status * New login layout (#269) * Public routes navigation * New login/register, login, register * Multiple meteor connection requests fixed * Nested attachments * Button component * TextInput android layout fixed * Register fixed * Thinner close modal button * Requests /me after login only one time * Static images moved * fix reconnect * fix ddp * fix custom emoji * New message layout (#273) * Grouping messages * Message layout * Users typing animation * Image attachment layout
2018-04-24 19:34:03 +00:00
2019-04-29 16:03:52 +00:00
const inMemorySchema = [usersTypingSchema, activeUsersSchema];
2019-04-08 12:35:28 +00:00
class DB {
databases = {
serversDB: new Realm({
path: 'default.realm',
schema: [
serversSchema
],
schemaVersion: 8,
2019-04-08 12:35:28 +00:00
migration: (oldRealm, newRealm) => {
if (oldRealm.schemaVersion >= 1 && newRealm.schemaVersion <= 8) {
2019-04-08 12:35:28 +00:00
const newServers = newRealm.objects('servers');
// eslint-disable-next-line no-plusplus
for (let i = 0; i < newServers.length; i++) {
newServers[i].roomsUpdatedAt = null;
}
}
}
}),
inMemoryDB: new Realm({
path: 'memory.realm',
schema: inMemorySchema,
2019-04-29 16:03:52 +00:00
schemaVersion: 2,
2019-04-08 12:35:28 +00:00
inMemory: true
})
}
deleteAll(...args) {
return this.database.write(() => this.database.deleteAll(...args));
}
delete(...args) {
return this.database.delete(...args);
}
write(...args) {
return this.database.write(...args);
}
create(...args) {
return this.database.create(...args);
}
objects(...args) {
return this.database.objects(...args);
}
2019-04-17 17:01:03 +00:00
objectForPrimaryKey(...args) {
return this.database.objectForPrimaryKey(...args);
}
get database() {
return this.databases.activeDB;
}
2019-04-08 12:35:28 +00:00
get memoryDatabase() {
return this.databases.inMemoryDB;
}
Beta (#265) * Fabric iOS * Fabric configured on iOS and Android * - react-native-fabric configured - login tracked * README updated * Run scripts from README updated * README scripts * get rooms and messages by rest * user status * more improves * more improves * send pong on timeout * fix some methods * more tests * rest messages * Room actions (#266) * Toggle notifications * Search messages * Invite users * Mute/Unmute users in room * rocket.cat messages * Room topic layout fixed * Starred messages loading onEndReached * Room actions onEndReached * Unnecessary login request * Login loading * Login services fixed * User presence layout * ïmproves on room actions view * Removed unnecessary data from SelectedUsersView * load few messages on open room, search message improve * fix loading messages forever * Removed state from search * Custom message time format * secureTextEntry layout * Reduce android app size * Roles subscription fix * Public routes navigation * fix reconnect * - New login/register, login, register * proguard * Login flux * App init/restore * Android layout fixes * Multiple meteor connection requests fixed * Nested attachments * Nested attachments * fix check status * New login layout (#269) * Public routes navigation * New login/register, login, register * Multiple meteor connection requests fixed * Nested attachments * Button component * TextInput android layout fixed * Register fixed * Thinner close modal button * Requests /me after login only one time * Static images moved * fix reconnect * fix ddp * fix custom emoji * New message layout (#273) * Grouping messages * Message layout * Users typing animation * Image attachment layout
2018-04-24 19:34:03 +00:00
setActiveDB(database = '') {
const path = database.replace(/(^\w+:|^)\/\//, '');
return this.databases.activeDB = new Realm({
path: `${ path }.realm`,
schema,
schemaVersion: 11,
2019-04-08 12:35:28 +00:00
migration: (oldRealm, newRealm) => {
if (oldRealm.schemaVersion >= 3 && newRealm.schemaVersion <= 11) {
2019-04-08 12:35:28 +00:00
const newSubs = newRealm.objects('subscriptions');
newRealm.delete(newSubs);
2019-04-08 12:35:28 +00:00
const newMessages = newRealm.objects('messages');
newRealm.delete(newMessages);
const newThreads = newRealm.objects('threads');
newRealm.delete(newThreads);
const newThreadMessages = newRealm.objects('threadMessages');
newRealm.delete(newThreadMessages);
2019-04-08 12:35:28 +00:00
}
if (newRealm.schemaVersion === 9) {
const newEmojis = newRealm.objects('customEmojis');
newRealm.delete(newEmojis);
const newSettings = newRealm.objects('settings');
newRealm.delete(newSettings);
}
2019-04-08 12:35:28 +00:00
}
});
}
}
2019-04-04 18:08:40 +00:00
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);
}
}