allow change default values, fix loading search users (#14177)

<!-- INSTRUCTION: Your Pull Request name should start with one of the following tags -->
<!-- [NEW] For new features -->
<!-- [FIX] For bug fixes -->
<!-- [BREAK] For pull requests including breaking changes -->

<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->


<!-- INSTRUCTION: Link to a https://github.com/RocketChat/docs PR with added/updated documentation or an update to the missing/outdated documentation list, see https://rocket.chat/docs/contributing/documentation/  -->

<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
pull/14214/head
Guilherme Gazzo 6 years ago committed by GitHub
parent e779a23f48
commit 51e66eaffb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      app/discussion/client/views/creationDialog/CreateDiscussion.html
  2. 67
      app/emoji/client/emojiParser.js
  3. 45
      app/highlight-words/client/client.js
  4. 44
      app/highlight-words/client/helper.js
  5. 26
      app/highlight-words/tests/helper.tests.js
  6. 42
      app/lib/client/lib/formatDate.js
  7. 115
      app/logger/client/logger.js
  8. 18
      app/mentions/client/client.js
  9. 2
      app/theme/client/imports/forms/popup-list.css
  10. 10
      app/threads/client/flextab/thread.js
  11. 4
      app/threads/client/flextab/threads.js
  12. 4
      app/ui-message/client/message.html
  13. 13
      app/ui-message/client/message.js
  14. 6
      app/ui-utils/client/config.js
  15. 3
      app/ui-utils/client/lib/RoomHistoryManager.js
  16. 4
      app/ui-utils/client/lib/RoomManager.js
  17. 18
      app/ui/client/components/popupList.html
  18. 2
      app/ui/client/components/popupList.js
  19. 9
      app/ui/client/views/app/createChannel.html
  20. 34
      package-lock.json

@ -96,13 +96,11 @@
<input type="text" id="{{name}}" class="rc-tags__input" placeholder="{{_ placeholder}}" name="{{name}}" autocomplete="off" {{disabled}} />
</div>
</div>
{{#with config}} {{#if autocomplete 'isShowing'}}
<div class="dropdown-in">
{{#if autocomplete 'isLoaded'}}
{{> popupList data=config items=items}}
{{#with config}}
{{#if autocomplete 'isShowing'}}
{{> popupList data=config items=items ready=(autocomplete 'isLoaded')}}
{{/if}}
</div>
{{/if}} {{/with}}
{{/with}}
</label>
<div class="rc-input__description">{{ description }}</div>
</div>

@ -1,61 +1,62 @@
import s from 'underscore.string';
import { Meteor } from 'meteor/meteor';
import { Tracker } from 'meteor/tracker';
import { getUserPreference } from '../../utils';
import { callbacks } from '../../callbacks';
import { emoji } from '../lib/rocketchat';
import { isSetNotNull } from './function-isSet';
import s from 'underscore.string';
/*
* emojiParser is a function that will replace emojis
* @param {Object} message - The message object
*/
callbacks.add('renderMessage', (message) => {
if (isSetNotNull(() => getUserPreference(Meteor.userId(), 'useEmojis')) &&
!getUserPreference(Meteor.userId(), 'useEmojis')) {
return message;
Tracker.autorun(() => {
if (!getUserPreference(Meteor.userId(), 'useEmojis')) {
return callbacks.remove('renderMessage', 'emoji');
}
callbacks.add('renderMessage', (message) => {
if (s.trim(message.html)) {
// &#39; to apostrophe (') for emojis such as :')
message.html = message.html.replace(/&#39;/g, '\'');
// '<br>' to ' <br> ' for emojis such at line breaks
message.html = message.html.replace(/<br>/g, ' <br> ');
if (s.trim(message.html)) {
// &#39; to apostrophe (') for emojis such as :')
message.html = message.html.replace(/&#39;/g, '\'');
message.html = Object.entries(emoji.packages).reduce((value, [, emojiPackage]) => emojiPackage.render(value), message.html);
// '<br>' to ' <br> ' for emojis such at line breaks
message.html = message.html.replace(/<br>/g, ' <br> ');
const checkEmojiOnly = $(`<div>${ message.html }</div>`);
let emojiOnly = true;
Object.keys(emoji.packages).forEach((emojiPackage) => {
message.html = emoji.packages[emojiPackage].render(message.html);
});
const checkEmojiOnly = $(`<div>${ message.html }</div>`);
let emojiOnly = true;
for (const childNode in checkEmojiOnly[0].childNodes) {
if (checkEmojiOnly[0].childNodes.hasOwnProperty(childNode)) {
const child = $(checkEmojiOnly[0].childNodes[childNode]);
for (let i = 0, len = checkEmojiOnly[0].childNodes.length; i < len; i++) {
const childNode = checkEmojiOnly[0].childNodes[i];
if (child.hasClass('emoji') || child.hasClass('emojione')) {
checkEmojiOnly[0].childNodes[childNode] = child.addClass('big');
if (childNode.classList && (childNode.classList.contains('emoji') || childNode.classList.contains('emojione'))) {
childNode.classList.add('big');
continue;
}
if (s.trim(child.text()) === '') {
if (s.trim(childNode.innerText) === '') {
continue;
}
emojiOnly = false;
break;
}
}
if (emojiOnly) {
message.html = checkEmojiOnly.unwrap().html();
}
if (emojiOnly) {
message.html = checkEmojiOnly.unwrap().html();
}
// apostrophe (') back to &#39;
message.html = message.html.replace(/\'/g, '&#39;');
// apostrophe (') back to &#39;
message.html = message.html.replace(/\'/g, '&#39;');
// apostrophe ' <br> ' back to '<br>'
message.html = message.html.replace(/ <br> /g, '<br>');
}
// apostrophe ' <br> ' back to '<br>'
message.html = message.html.replace(/ <br> /g, '<br>');
}
return message;
}, callbacks.priority.LOW, 'emoji');
return message;
}, callbacks.priority.LOW, 'emoji');
});

@ -2,28 +2,39 @@
* Highlights is a named function that will process Highlights
* @param {Object} message - The message object
*/
import _ from 'underscore';
import s from 'underscore.string';
import { Meteor } from 'meteor/meteor';
import { Tracker } from 'meteor/tracker';
import { callbacks } from '../../callbacks';
import { getUserPreference } from '../../utils';
import _ from 'underscore';
import s from 'underscore.string';
import { highlightWords } from './helper';
import { highlightWords, getRegexHighlight, getRegexHighlightUrl } from './helper';
function HighlightWordsClient(message) {
let msg = message;
if (!_.isString(message)) {
if (s.trim(message.html)) {
msg = message.html;
} else {
return message;
}
Tracker.autorun(() => {
const toHighlight = (getUserPreference(Meteor.userId(), 'highlights') || []).filter((highlight) => !s.isBlank(highlight)).map((highlight) => ({
highlight,
regex: getRegexHighlight(highlight),
urlRegex: getRegexHighlightUrl(highlight),
}));
if (!toHighlight.length) {
return callbacks.remove('renderMessage', 'highlight-words');
}
const to_highlight = getUserPreference(Meteor.user(), 'highlights');
msg = highlightWords(msg, to_highlight);
function HighlightWordsClient(message) {
let msg = message;
message.html = msg;
return message;
}
if (!_.isString(message)) {
if (!s.trim(message.html)) {
return message;
}
msg = message.html;
}
callbacks.add('renderMessage', HighlightWordsClient, callbacks.priority.MEDIUM + 1, 'highlight-words');
message.html = highlightWords(msg, toHighlight);
return message;
}
callbacks.add('renderMessage', HighlightWordsClient, callbacks.priority.MEDIUM + 1, 'highlight-words');
});

@ -1,42 +1,28 @@
import s from 'underscore.string';
export const checkHighlightedWordsInUrls = (msg, highlight) => {
const urlRegex = new RegExp(`https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)(${ s.escapeRegExp(highlight) })\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)`, 'gmi');
const urlMatches = msg.match(urlRegex);
return urlMatches;
};
export const checkHighlightedWordsInUrls = (msg, urlRegex) => msg.match(urlRegex);
export const removeHighlightedUrls = (msg, highlight, urlMatches) => {
const highlightRegex = new RegExp(highlight, 'gmi');
urlMatches.forEach((match) => {
const highlightRegex = new RegExp(highlight, 'gmi');
return urlMatches.reduce((msg, match) => {
const withTemplate = match.replace(highlightRegex, `<span class="highlight-text">${ highlight }</span>`);
const regexWithTemplate = new RegExp(withTemplate, 'i');
msg = msg.replace(regexWithTemplate, match);
});
return msg;
return msg.replace(regexWithTemplate, match);
}, msg);
};
export const highlightWords = (msg, to_highlight) => {
const highlightTemplate = '$1<span class="highlight-text">$2</span>$3';
const highlightTemplate = '$1<span class="highlight-text">$2</span>$3';
if (Array.isArray(to_highlight)) {
to_highlight.forEach((highlight) => {
if (!s.isBlank(highlight)) {
const regex = new RegExp(`(^|\\b|[\\s\\n\\r\\t.,،'\\\"\\+!?:-])(${ s.escapeRegExp(highlight) })($|\\b|[\\s\\n\\r\\t.,،'\\\"\\+!?:-])(?![^<]*>|[^<>]*<\\/)`, 'gmi');
const urlMatches = checkHighlightedWordsInUrls(msg, highlight);
export const getRegexHighlight = (highlight) => new RegExp(`(^|\\b|[\\s\\n\\r\\t.,،'\\\"\\+!?:-])(${ s.escapeRegExp(highlight) })($|\\b|[\\s\\n\\r\\t.,،'\\\"\\+!?:-])(?![^<]*>|[^<>]*<\\/)`, 'gmi');
msg = msg.replace(regex, highlightTemplate);
export const getRegexHighlightUrl = (highlight) => new RegExp(`https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)(${ s.escapeRegExp(highlight) })\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)`, 'gmi');
if (urlMatches) {
msg = removeHighlightedUrls(msg, highlight, urlMatches);
}
}
});
}
export const highlightWords = (msg, highlights) => highlights.reduce((msg, { highlight, regex, urlRegex }) => {
const urlMatches = checkHighlightedWordsInUrls(msg, urlRegex);
if (!urlMatches) {
return msg.replace(regex, highlightTemplate);
return msg;
};
}
return removeHighlightedUrls(msg.replace(regex, highlightTemplate), highlight, urlMatches);
}, msg);

@ -2,32 +2,48 @@
import 'babel-polyfill';
import assert from 'assert';
import { highlightWords } from '../client/helper';
import { highlightWords, getRegexHighlight, getRegexHighlightUrl } from '../client/helper';
describe('helper', () => {
describe('highlightWords', () => {
it('highlights the correct words', () => {
const res = highlightWords('here is some word', ['word']);
const res = highlightWords('here is some word', ['word'].map((highlight) => ({
highlight,
regex: getRegexHighlight(highlight),
urlRegex: getRegexHighlightUrl(highlight),
})));
assert.equal(res, 'here is some <span class="highlight-text">word</span>');
});
describe('handles links', () => {
it('not highlighting one link', () => {
const res = highlightWords('here we go https://somedomain.com/here-some.word/pulls more words after', ['word']);
const res = highlightWords('here we go https://somedomain.com/here-some.word/pulls more words after', ['word'].map((highlight) => ({
highlight,
regex: getRegexHighlight(highlight),
urlRegex: getRegexHighlightUrl(highlight),
})));
assert.equal(res, 'here we go https://somedomain.com/here-some.word/pulls more words after');
});
it('not highlighting two links', () => {
const msg = 'here https://somedomain.com/here-some-foo/pulls more words after http://www.domain.com/some.foo/bar words after';
const res = highlightWords(msg, ['foo']);
const res = highlightWords(msg, ['foo'].map((highlight) => ({
highlight,
regex: getRegexHighlight(highlight),
urlRegex: getRegexHighlightUrl(highlight),
})));
assert.equal(res, msg);
});
it('not highlighting link but keep words on message highlighted', () => {
const res = highlightWords('here we go https://somedomain.com/here-some.foo/pulls more foo after', ['foo']);
const res = highlightWords('here we go https://somedomain.com/here-some.foo/pulls more foo after', ['foo'].map((highlight) => ({
highlight,
regex: getRegexHighlight(highlight),
urlRegex: getRegexHighlightUrl(highlight),
})));
assert.equal(res, 'here we go https://somedomain.com/here-some.foo/pulls more <span class="highlight-text">foo</span> after');
});

@ -1,21 +1,34 @@
import moment from 'moment';
import { Meteor } from 'meteor/meteor';
import { Tracker } from 'meteor/tracker';
import { getUserPreference, t } from '../../../utils';
import { settings } from '../../../settings';
import moment from 'moment';
let lastDay = t('yesterday');
let clockMode;
let sameDay;
const dayFormat = ['h:mm A', 'H:mm'];
Meteor.startup(() => Tracker.autorun(() => {
clockMode = getUserPreference(Meteor.userId(), 'clockMode', false);
sameDay = dayFormat[clockMode - 1] || 'h:mm A';
lastDay = t('yesterday');
}));
export const formatTime = (time) => {
switch (getUserPreference(Meteor.userId(), 'clockMode', false)) {
switch (clockMode) {
case 1:
return moment(time).format('h:mm A');
case 2:
return moment(time).format('H:mm');
return moment(time).format(sameDay);
default:
return moment(time).format(settings.get('Message_TimeFormat'));
}
};
export const formatDateAndTime = (time) => {
switch (getUserPreference(Meteor.userId(), 'clockMode', false)) {
switch (clockMode) {
case 1:
return moment(time).format('MMMM D, Y h:mm A');
case 2:
@ -25,15 +38,16 @@ export const formatDateAndTime = (time) => {
}
};
export const timeAgo = (time) => {
const now = new Date();
const yesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
return (
(now.getDate() === time.getDate() && moment(time).format('LT')) ||
(yesterday.getDate() === time.getDate() && t('yesterday')) ||
moment(time).format('L')
);
const sameElse = function(now) {
const diff = Math.ceil(this.diff(now, 'years', true));
return diff < 0 ? 'MMM D YYYY' : 'MMM D';
};
export const timeAgo = (date) => moment(date).calendar(null, {
lastDay: `[${ lastDay }]`,
sameDay,
lastWeek: 'dddd',
sameElse,
});
export const formatDate = (time) => moment(time).format(settings.get('Message_DateFormat'));

@ -1,35 +1,70 @@
import { Template } from 'meteor/templating';
import _ from 'underscore';
Template.log = false;
import { getConfig } from '../../ui-utils/client/config';
Template.logMatch = /.*/;
Template.log = !!(getConfig('debug') || getConfig('debug-template'));
if (Template.log) {
Template.enableLogs = function(log) {
Template.logMatch = /.*/;
if (log === false) {
return Template.log = false;
} else {
Template.log = true;
if (log instanceof RegExp) {
return Template.logMatch = log;
Template.enableLogs = function(log) {
Template.logMatch = /.*/;
if (log === false) {
return Template.log = false;
} else {
Template.log = true;
if (log instanceof RegExp) {
return Template.logMatch = log;
}
}
}
};
};
const wrapHelpersAndEvents = function(original, prefix, color) {
return function(dict) {
const wrapHelpersAndEvents = function(original, prefix, color) {
return function(dict) {
const template = this;
const fn1 = function(name, fn) {
if (fn instanceof Function) {
return dict[name] = function(...args) {
const template = this;
const fn1 = function(name, fn) {
if (fn instanceof Function) {
return dict[name] = function(...args) {
const result = fn.apply(this, args);
if (Template.log === true) {
const completeName = `${ prefix }:${ template.viewName.replace('Template.', '') }.${ name }`;
if (Template.logMatch.test(completeName)) {
console.log(`%c${ completeName }`, `color: ${ color }`, {
args,
scope: this,
result,
});
}
}
return result;
};
}
};
_.each(name, (fn, name) => {
fn1(name, fn);
});
return original.call(template, dict);
};
};
Template.prototype.helpers = wrapHelpersAndEvents(Template.prototype.helpers, 'helper', 'blue');
Template.prototype.events = wrapHelpersAndEvents(Template.prototype.events, 'event', 'green');
const wrapLifeCycle = function(original, prefix, color) {
return function(fn) {
const template = this;
if (fn instanceof Function) {
const wrap = function(...args) {
const result = fn.apply(this, args);
if (Template.log === true) {
const completeName = `${ prefix }:${ template.viewName.replace('Template.', '') }.${ name }`;
if (Template.logMatch.test(completeName)) {
console.log(`%c${ completeName }`, `color: ${ color }`, {
console.log(`%c${ completeName }`, `color: ${ color }; font-weight: bold`, {
args,
scope: this,
result,
@ -38,46 +73,16 @@ const wrapHelpersAndEvents = function(original, prefix, color) {
}
return result;
};
return original.call(template, wrap);
} else {
return original.call(template, fn);
}
};
_.each(name, (fn, name) => {
fn1(name, fn);
});
return original.call(template, dict);
};
};
Template.prototype.helpers = wrapHelpersAndEvents(Template.prototype.helpers, 'helper', 'blue');
Template.prototype.events = wrapHelpersAndEvents(Template.prototype.events, 'event', 'green');
const wrapLifeCycle = function(original, prefix, color) {
return function(fn) {
const template = this;
if (fn instanceof Function) {
const wrap = function(...args) {
const result = fn.apply(this, args);
if (Template.log === true) {
const completeName = `${ prefix }:${ template.viewName.replace('Template.', '') }.${ name }`;
if (Template.logMatch.test(completeName)) {
console.log(`%c${ completeName }`, `color: ${ color }; font-weight: bold`, {
args,
scope: this,
result,
});
}
}
return result;
};
return original.call(template, wrap);
} else {
return original.call(template, fn);
}
};
};
Template.prototype.onCreated = wrapLifeCycle(Template.prototype.onCreated, 'onCreated', 'blue');
Template.prototype.onCreated = wrapLifeCycle(Template.prototype.onCreated, 'onCreated', 'blue');
Template.prototype.onRendered = wrapLifeCycle(Template.prototype.onRendered, 'onRendered', 'green');
Template.prototype.onRendered = wrapLifeCycle(Template.prototype.onRendered, 'onRendered', 'green');
Template.prototype.onDestroyed = wrapLifeCycle(Template.prototype.onDestroyed, 'onDestroyed', 'red');
Template.prototype.onDestroyed = wrapLifeCycle(Template.prototype.onDestroyed, 'onDestroyed', 'red');
}

@ -1,12 +1,24 @@
import { Meteor } from 'meteor/meteor';
import { Tracker } from 'meteor/tracker';
import { callbacks } from '../../callbacks';
import { settings } from '../../settings';
import { MentionsParser } from '../lib/MentionsParser';
let me;
let useRealName;
let pattern;
Meteor.startup(() => Tracker.autorun(() => {
me = Meteor.userId() && Meteor.user().username;
pattern = settings.get('UTF8_Names_Validation');
useRealName = settings.get('UI_Use_Real_Name');
}));
const instance = new MentionsParser({
pattern: () => settings.get('UTF8_Names_Validation'),
useRealName: () => settings.get('UI_Use_Real_Name'),
me: () => Meteor.userId() && Meteor.user().username,
pattern: () => pattern,
useRealName: () => useRealName,
me: () => me,
});
callbacks.add('renderMessage', (message) => instance.parse(message), callbacks.priority.MEDIUM, 'mentions-message');

@ -5,8 +5,6 @@
width: 100%;
padding: 0 4px;
&__list {
overflow-y: auto;

@ -75,8 +75,6 @@ Template.thread.onRendered(function() {
this.chatMessages.initializeWrapper(this.find('.js-scroll-thread'));
this.chatMessages.initializeInput(this.find('.js-input-message'), { rid, tmid });
this.chatMessages.wrapper.scrollTop = this.chatMessages.wrapper.scrollHeight - this.chatMessages.wrapper.clientHeight;
this.sendToBottom = _.throttle(() => {
this.chatMessages.wrapper.scrollTop = this.chatMessages.wrapper.scrollHeight;
}, 300);
@ -94,7 +92,13 @@ Template.thread.onRendered(function() {
const tmid = this.state.get('tmid');
this.threadsObserve && this.threadsObserve.stop();
this.threadsObserve = Messages.find({ tmid, _updatedAt: { $gt: new Date() } }).observe({
this.threadsObserve = Messages.find({ tmid, _updatedAt: { $gt: new Date() } }, {
fields: {
collapsed: 0,
threadMsg: 0,
repliesCount: 0,
},
}).observe({
added: ({ _id, ...message }) => {
const { atBottom } = this;
this.Threads.upsert({ _id }, message);

@ -10,12 +10,14 @@ import { call } from '../../../ui-utils';
import { Messages, Subscriptions } from '../../../models';
import { messageContext } from '../../../ui-utils/client/lib/messageContext';
import { messageArgs } from '../../../ui-utils/client/lib/messageArgs';
import { getConfig } from '../../../ui-utils/client/config';
import { upsert } from '../upsert';
import './threads.html';
const LIST_SIZE = 50;
const LIST_SIZE = parseInt(getConfig('threadsListSize')) || 50;
const sort = { tlm: -1 };
Template.threads.events({

@ -101,7 +101,7 @@
{{_ "No_messages_yet" }}
</button>
{{/if}}
<span class="discussion-reply-lm">{{ formatDate msg.dlm }}</span>
<span class="discussion-reply-lm">{{ formatDateAndTime msg.dlm }}</span>
</div>
{{/if}}
@ -111,7 +111,7 @@
{{> icon icon="thread"}}
<span class='reply-counter'>{{msg.tcount}}</span>&nbsp;{{_ i18nKeyReply}}
</button>
<span class="discussion-reply-lm">{{ formatDate msg.tlm}}</span>
<span class="discussion-reply-lm">{{ formatDateAndTime msg.tlm}}</span>
</div>
{{/if}}

@ -1,12 +1,11 @@
import _ from 'underscore';
import moment from 'moment';
import { Meteor } from 'meteor/meteor';
import { Blaze } from 'meteor/blaze';
import { Template } from 'meteor/templating';
import { TAPi18n } from 'meteor/tap:i18n';
import { timeAgo } from '../../lib/client/lib/formatDate';
import { timeAgo, formatDateAndTime } from '../../lib/client/lib/formatDate';
import { DateFormat } from '../../lib/client';
import { renderMessageBody, MessageTypes, MessageAction, call, normalizeThreadMessage } from '../../ui-utils/client';
import { RoomRoles, UserRoles, Roles, Messages } from '../../models/client';
@ -84,9 +83,7 @@ Template.message.helpers({
? 'replies'
: 'reply';
},
formatDate(date) {
return moment(date).format('LLL');
},
formatDateAndTime,
encodeURI(text) {
return encodeURI(text);
},
@ -519,10 +516,6 @@ const setNewDayAndGroup = (currentNode, previousNode, forceDate, period, noDate)
classList.add('new-day');
}
if (previousDataset.tmid !== currentDataset.tmid) {
return classList.remove('sequential');
}
if (previousDataset.username !== currentDataset.username || parseInt(currentDataset.timestamp) - parseInt(previousDataset.timestamp) > period) {
return classList.remove('sequential');
}
@ -559,7 +552,7 @@ Template.message.onViewRendered = function() {
nextNode.classList.remove('new-day');
}
if (nextDataset.groupable !== 'false') {
if (nextDataset.tmid !== currentDataset.tmid || nextDataset.username !== currentDataset.username || parseInt(nextDataset.timestamp) - parseInt(currentDataset.timestamp) > settings.Message_GroupingPeriod) {
if (nextDataset.username !== currentDataset.username || parseInt(nextDataset.timestamp) - parseInt(currentDataset.timestamp) > settings.Message_GroupingPeriod) {
nextNode.classList.remove('sequential');
} else if (!nextNode.classList.contains('new-day') && !currentNode.classList.contains('temp') && !currentNode.dataset.tmid) {
nextNode.classList.add('sequential');

@ -0,0 +1,6 @@
const url = new URL(window.location);
const keys = new Set();
export const getConfig = (key) => {
keys.add(key);
return url.searchParams.get(key) || localStorage.getItem(`rc-config-${ key }`);
};

@ -4,6 +4,7 @@ import { Meteor } from 'meteor/meteor';
import { ReactiveVar } from 'meteor/reactive-var';
import { Blaze } from 'meteor/blaze';
import { ChatMessage, ChatSubscription, ChatRoom } from '../../../models';
import { getConfig } from '../config';
import { RoomManager } from './RoomManager';
import { readMessage } from './readMessages';
import { renderMessageBody } from './renderMessageBody';
@ -66,7 +67,7 @@ function upsertMessageBulk({ msgs, subscription }) {
});
}
const defaultLimit = parseInt(localStorage && localStorage.getItem('rc-defaultLimit')) || 50 ;
const defaultLimit = parseInt(getConfig('roomListLimit')) || 50 ;
export const RoomHistoryManager = new class {
constructor() {

@ -14,10 +14,10 @@ import { CachedCollectionManager } from '../../../ui-cached-collection';
import _ from 'underscore';
import { upsertMessage, RoomHistoryManager } from './RoomHistoryManager';
import { mainReady } from './mainReady';
import { getConfig } from '../config';
const maxRoomsOpen = parseInt(localStorage && localStorage.getItem('rc-maxRoomsOpen')) || 5 ;
const maxRoomsOpen = parseInt(getConfig('maxRoomsOpen')) || 5 ;
const onDeleteMessageStream = (msg) => {
ChatMessage.remove({ _id: msg._id });

@ -6,16 +6,20 @@
<template name="popupList_default">
<ul class="rc-popup-list__list">
{{#each item in items}}
{{> Template.dynamic config item data=data}}
{{#if loading}}
{{> popupList_loading }}
{{else}}
{{> Template.dynamic template=noMatchTemplate}}
{{/each}}
{{#each item in items}}
{{> Template.dynamic config item data=data}}
{{else}}
{{> Template.dynamic template=noMatchTemplate}}
{{/each}}
{{/if}}
</ul>
</template>
<template name="popupList_item_default">
<li class="rc-popup-list__item">
<li class="rc-popup-list__item">
<span class="rc-popup-list__item-image">
{{>avatar username=item.username}}
</span>
@ -27,6 +31,10 @@
</li>
</template>
<template name="popupList_loading">
<p>{{_ "Loading"}}.</p>
</template>
<template name="popupList_item_channel">
<li class="rc-popup-list__item">
<span class="rc-popup-list__item-image">

@ -6,6 +6,8 @@ Template.popupList.helpers({
return {
template: this.data.template_list || 'popupList_default',
data: {
ready: this.ready,
loading: !this.ready,
noMatchTemplate: this.data.noMatchTemplate,
template_item :this.data.template_item || 'popupList_item_default',
items: this.items,

@ -96,17 +96,12 @@
{{#each user in selectedUsers}}
{{> tag user}}
{{/each}}
<input type="text" class="rc-tags__input" placeholder="{{_ "Username_Placeholder"}}"
name="users" autocomplete="off"/>
<input type="text" class="rc-tags__input" placeholder="{{_ "Username_Placeholder"}}" name="users" autocomplete="off"/>
</div>
</div>
{{#with config}}
{{#if autocomplete 'isShowing'}}
<div class="dropdown-in">
{{> popupList data=config items=items}}
</div>
{{> popupList data=config items=items ready=(autocomplete 'isLoaded')}}
{{/if}}
{{/with}}
</label>

34
package-lock.json generated

@ -8888,6 +8888,18 @@
"hoek": "2.x.x",
"joi": "6.x.x",
"wreck": "5.x.x"
},
"dependencies": {
"wreck": {
"version": "5.6.1",
"resolved": "http://registry.npmjs.org/wreck/-/wreck-5.6.1.tgz",
"integrity": "sha1-r/ADBAATiJ11YZtccYcN0qjdBpo=",
"dev": true,
"requires": {
"boom": "2.x.x",
"hoek": "2.x.x"
}
}
}
},
"heavy": {
@ -8899,6 +8911,20 @@
"boom": "2.x.x",
"hoek": "2.x.x",
"joi": "5.x.x"
},
"dependencies": {
"joi": {
"version": "5.1.0",
"resolved": "http://registry.npmjs.org/joi/-/joi-5.1.0.tgz",
"integrity": "sha1-FSrQfbjunGQBmX/1/SwSiWBwv1g=",
"dev": true,
"requires": {
"hoek": "^2.2.x",
"isemail": "1.x.x",
"moment": "2.x.x",
"topo": "1.x.x"
}
}
}
},
"hoek": {
@ -10884,7 +10910,7 @@
},
"load-json-file": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
"resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
"integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
"dev": true,
"requires": {
@ -10896,7 +10922,7 @@
"dependencies": {
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
}
@ -13863,7 +13889,7 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
},
"simple-get": {
@ -14217,7 +14243,7 @@
},
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
}

Loading…
Cancel
Save