diff --git a/app/containers/message/Markdown.js b/app/containers/message/Markdown.js
index 11dba2055..5b3a59a34 100644
--- a/app/containers/message/Markdown.js
+++ b/app/containers/message/Markdown.js
@@ -14,98 +14,90 @@ const formatText = text => text.replace(
(match, url, title) => `[${ title }](${ url })`
);
-export default class Markdown extends React.Component {
- shouldComponentUpdate(nextProps) {
- const { msg } = this.props;
- return nextProps.msg !== msg;
+const Markdown = React.memo(({
+ msg, customEmojis, style, rules, baseUrl, username, edited, numberOfLines
+}) => {
+ if (!msg) {
+ return null;
}
-
- render() {
- const {
- msg, customEmojis, style, rules, baseUrl, username, edited, numberOfLines
- } = this.props;
- if (!msg) {
- return null;
- }
- let m = formatText(msg);
- if (m) {
- m = emojify(m, { output: 'unicode' });
- }
- m = m.replace(/^\[([^\]]*)\]\(([^)]*)\)/, '').trim();
- if (numberOfLines > 0) {
- m = m.replace(/[\n]+/g, '\n').trim();
- }
- return (
- (
- // eslint-disable-next-line
-
- {children}
- {edited ? (edited) : null}
-
- ),
- mention: (node) => {
- const { content, key } = node;
- let mentionStyle = styles.mention;
- if (content === 'all' || content === 'here') {
- mentionStyle = {
- ...mentionStyle,
- ...styles.mentionAll
- };
- } else if (content === username) {
- mentionStyle = {
- ...mentionStyle,
- ...styles.mentionLoggedUser
- };
- }
- return (
-
- {content}
-
- );
- },
- hashtag: node => (
-
- #{node.content}
-
- ),
- emoji: (node) => {
- if (node.children && node.children.length && node.children[0].content) {
- const { content } = node.children[0];
- const emojiExtension = customEmojis[content];
- if (emojiExtension) {
- const emoji = { extension: emojiExtension, content };
- return ;
- }
- return :{content}:;
- }
- return null;
- },
- hardbreak: () => null,
- blocklink: () => null,
- image: node => (
-
- ),
- ...rules
- }}
- style={{
- paragraph: styles.paragraph,
- text: styles.text,
- codeInline: styles.codeInline,
- codeBlock: styles.codeBlock,
- link: styles.link,
- ...style
- }}
- plugins={[
- new PluginContainer(MarkdownFlowdock),
- new PluginContainer(MarkdownEmojiPlugin)
- ]}
- >{m}
-
- );
+ let m = formatText(msg);
+ if (m) {
+ m = emojify(m, { output: 'unicode' });
}
-}
+ m = m.replace(/^\[([^\]]*)\]\(([^)]*)\)/, '').trim();
+ if (numberOfLines > 0) {
+ m = m.replace(/[\n]+/g, '\n').trim();
+ }
+ return (
+ (
+ // eslint-disable-next-line
+
+ {children}
+ {edited ? (edited) : null}
+
+ ),
+ mention: (node) => {
+ const { content, key } = node;
+ let mentionStyle = styles.mention;
+ if (content === 'all' || content === 'here') {
+ mentionStyle = {
+ ...mentionStyle,
+ ...styles.mentionAll
+ };
+ } else if (content === username) {
+ mentionStyle = {
+ ...mentionStyle,
+ ...styles.mentionLoggedUser
+ };
+ }
+ return (
+
+ {content}
+
+ );
+ },
+ hashtag: node => (
+
+ #{node.content}
+
+ ),
+ emoji: (node) => {
+ if (node.children && node.children.length && node.children[0].content) {
+ const { content } = node.children[0];
+ const emojiExtension = customEmojis[content];
+ if (emojiExtension) {
+ const emoji = { extension: emojiExtension, content };
+ return ;
+ }
+ return :{content}:;
+ }
+ return null;
+ },
+ hardbreak: () => null,
+ blocklink: () => null,
+ image: node => (
+
+ ),
+ ...rules
+ }}
+ style={{
+ paragraph: styles.paragraph,
+ text: styles.text,
+ codeInline: styles.codeInline,
+ codeBlock: styles.codeBlock,
+ link: styles.link,
+ ...style
+ }}
+ plugins={[
+ new PluginContainer(MarkdownFlowdock),
+ new PluginContainer(MarkdownEmojiPlugin)
+ ]}
+ >{m}
+
+ );
+}, (prevProps, nextProps) => prevProps.msg === nextProps.msg);
Markdown.propTypes = {
msg: PropTypes.string,
@@ -117,3 +109,5 @@ Markdown.propTypes = {
edited: PropTypes.bool,
numberOfLines: PropTypes.number
};
+
+export default Markdown;
diff --git a/app/lib/methods/getCustomEmojis.js b/app/lib/methods/getCustomEmojis.js
index adcb2e83c..207ef446c 100644
--- a/app/lib/methods/getCustomEmojis.js
+++ b/app/lib/methods/getCustomEmojis.js
@@ -1,39 +1,83 @@
import { InteractionManager } from 'react-native';
+import semver from 'semver';
import reduxStore from '../createStore';
import database from '../realm';
import * as actions from '../../actions';
import log from '../../utils/log';
-const getLastMessage = () => {
- const setting = database.objects('customEmojis').sorted('_updatedAt', true)[0];
- return setting && setting._updatedAt;
+const getUpdatedSince = () => {
+ const emoji = database.objects('customEmojis').sorted('_updatedAt', true)[0];
+ return emoji && emoji._updatedAt.toISOString();
};
-// TODO: fix api (get emojis by date/version....)
+const create = (customEmojis) => {
+ if (customEmojis && customEmojis.length) {
+ customEmojis.forEach((emoji) => {
+ try {
+ database.create('customEmojis', emoji, true);
+ } catch (e) {
+ log('getEmojis create', e);
+ }
+ });
+ }
+};
+
+
export default async function() {
try {
- const lastMessage = getLastMessage();
- // RC 0.61.0
- const result = await this.sdk.get('emoji-custom');
- let { emojis } = result;
- emojis = emojis.filter(emoji => !lastMessage || emoji._updatedAt > lastMessage);
- if (emojis.length === 0) {
- return;
- }
- emojis = this._prepareEmojis(emojis);
- InteractionManager.runAfterInteractions(() => {
- database.write(() => {
- emojis.forEach((emoji) => {
- try {
- database.create('customEmojis', emoji, true);
- } catch (e) {
- log('create custom emojis', e);
- }
+ const serverVersion = reduxStore.getState().server.version;
+ const updatedSince = getUpdatedSince();
+
+ // if server version is lower than 0.75.0, fetches from old api
+ if (semver.lt(serverVersion, '0.75.0')) {
+ // RC 0.61.0
+ const result = await this.sdk.get('emoji-custom');
+
+ InteractionManager.runAfterInteractions(() => {
+ let { emojis } = result;
+ emojis = emojis.filter(emoji => !updatedSince || emoji._updatedAt > updatedSince);
+ database.write(() => {
+ create(emojis);
});
+ reduxStore.dispatch(actions.setCustomEmojis(this.parseEmojis(result.emojis)));
});
- });
- reduxStore.dispatch(actions.setCustomEmojis(this.parseEmojis(emojis)));
+ } else {
+ const params = {};
+ if (updatedSince) {
+ params.updatedSince = updatedSince;
+ }
+
+ // RC 0.75.0
+ const result = await this.sdk.get('emoji-custom.list', params);
+
+ if (!result.success) {
+ return;
+ }
+
+ InteractionManager.runAfterInteractions(
+ () => database.write(() => {
+ const { emojis } = result;
+ create(emojis.update);
+
+ if (emojis.delete && emojis.delete.length) {
+ emojis.delete.forEach((emoji) => {
+ try {
+ const emojiRecord = database.objectForPrimaryKey('customEmojis', emoji._id);
+ if (emojiRecord) {
+ database.delete(emojiRecord);
+ }
+ } catch (e) {
+ log('getEmojis delete', e);
+ }
+ });
+ }
+
+ const allEmojis = database.objects('customEmojis');
+ reduxStore.dispatch(actions.setCustomEmojis(this.parseEmojis(allEmojis)));
+ })
+ );
+ }
} catch (e) {
log('getCustomEmojis', e);
}
diff --git a/app/lib/methods/helpers/mergeSubscriptionsRooms.js b/app/lib/methods/helpers/mergeSubscriptionsRooms.js
index c09caed51..7983cac08 100644
--- a/app/lib/methods/helpers/mergeSubscriptionsRooms.js
+++ b/app/lib/methods/helpers/mergeSubscriptionsRooms.js
@@ -24,6 +24,9 @@ export const merge = (subscription, room) => {
subscription.archived = room.archived;
subscription.joinCodeRequired = room.joinCodeRequired;
subscription.broadcast = room.broadcast;
+ if (!subscription.roles || !subscription.roles.length) {
+ subscription.roles = [];
+ }
if (room.muted && room.muted.length) {
subscription.muted = room.muted.filter(user => user).map(user => ({ value: user }));
diff --git a/app/lib/realm.js b/app/lib/realm.js
index 8c2bbc547..a36327349 100644
--- a/app/lib/realm.js
+++ b/app/lib/realm.js
@@ -286,21 +286,13 @@ const frequentlyUsedEmojiSchema = {
}
};
-const customEmojiAliasesSchema = {
- name: 'customEmojiAliases',
- primaryKey: 'value',
- properties: {
- value: 'string'
- }
-};
-
const customEmojisSchema = {
name: 'customEmojis',
primaryKey: '_id',
properties: {
_id: 'string',
name: 'string',
- aliases: { type: 'list', objectType: 'customEmojiAliases' },
+ aliases: 'string[]',
extension: 'string',
_updatedAt: { type: 'date', optional: true }
}
@@ -353,7 +345,6 @@ const schema = [
permissionsSchema,
url,
frequentlyUsedEmojiSchema,
- customEmojiAliasesSchema,
customEmojisSchema,
messagesReactionsSchema,
messagesReactionsUsernamesSchema,
@@ -428,7 +419,7 @@ class DB {
return this.databases.activeDB = new Realm({
path: `${ path }.realm`,
schema,
- schemaVersion: 8,
+ schemaVersion: 9,
migration: (oldRealm, newRealm) => {
if (oldRealm.schemaVersion >= 3 && newRealm.schemaVersion <= 8) {
const newSubs = newRealm.objects('subscriptions');
@@ -445,6 +436,14 @@ class DB {
const newThreadMessages = newRealm.objects('threadMessages');
newRealm.delete(newThreadMessages);
}
+ if (newRealm.schemaVersion === 9) {
+ const newSubs = newRealm.objects('subscriptions');
+ newRealm.delete(newSubs);
+ const newEmojis = newRealm.objects('customEmojis');
+ newRealm.delete(newEmojis);
+ const newSettings = newRealm.objects('settings');
+ newRealm.delete(newSettings);
+ }
}
});
}