- {{#if isReady}}
- {{> icon block="rc-input__icon-svg" icon="magnifier" }}
- {{else}}
+ {{#if isLoading}}
{{> loading }}
+ {{else}}
+ {{> icon block="rc-input__icon-svg" icon="magnifier" }}
{{/if}}
{{_ "No_results_found_for"}} {{.}} |
- {{/with}} {{/each}} {{#unless isReady}}
+ {{/with}} {{/each}} {{#if isLoading}}
| {{> loading}} |
- {{/unless}}
+ {{/if}}
{{/table}}
{{/unless}}
diff --git a/app/emoji-custom/client/admin/adminEmoji.js b/app/emoji-custom/client/admin/adminEmoji.js
index 1e6e04e053e..6bbf479fbe2 100644
--- a/app/emoji-custom/client/admin/adminEmoji.js
+++ b/app/emoji-custom/client/admin/adminEmoji.js
@@ -2,39 +2,24 @@ import { ReactiveVar } from 'meteor/reactive-var';
import { Tracker } from 'meteor/tracker';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { Template } from 'meteor/templating';
-import s from 'underscore.string';
+import _ from 'underscore';
-import { EmojiCustom } from '../../../models';
import { RocketChatTabBar, SideNav, TabBar } from '../../../ui-utils';
+import { APIClient } from '../../../utils/client';
+
+const LIST_SIZE = 50;
+const DEBOUNCE_TIME_TO_SEARCH_IN_MS = 500;
Template.adminEmoji.helpers({
searchText() {
const instance = Template.instance();
return instance.filter && instance.filter.get();
},
- isReady() {
- if (Template.instance().ready != null) {
- return Template.instance().ready.get();
- }
- return undefined;
- },
customemoji() {
- return Template.instance().customemoji();
+ return Template.instance().emojis.get();
},
isLoading() {
- if (Template.instance().ready != null) {
- if (!Template.instance().ready.get()) {
- return 'btn-loading';
- }
- }
- },
- hasMore() {
- if (Template.instance().limit != null) {
- if (typeof Template.instance().customemoji === 'function') {
- return Template.instance().limit.get() === Template.instance().customemoji().length;
- }
- }
- return false;
+ return Template.instance().isLoading.get();
},
flexData() {
return {
@@ -48,26 +33,32 @@ Template.adminEmoji.helpers({
if ((currentTarget.offsetHeight + currentTarget.scrollTop) < (currentTarget.scrollHeight - 100)) {
return;
}
- if (instance.limit.get() > instance.customemoji().length) {
- return false;
+ const emojis = instance.emojis.get();
+ if (instance.total.get() > emojis.length) {
+ instance.offset.set(instance.offset.get() + LIST_SIZE);
}
- instance.limit.set(instance.limit.get() + 50);
};
},
onTableItemClick() {
const instance = Template.instance();
return function({ _id }) {
- instance.tabBarData.set(EmojiCustom.findOne({ _id }));
+ instance.tabBarData.set({
+ emoji: instance.emojis.get().find((emoji) => emoji._id === _id),
+ onSuccess: instance.onSuccessCallback,
+ });
instance.tabBar.open('admin-emoji-info');
};
},
});
-Template.adminEmoji.onCreated(function() {
+Template.adminEmoji.onCreated(async function() {
const instance = this;
- this.limit = new ReactiveVar(50);
+ this.emojis = new ReactiveVar([]);
+ this.offset = new ReactiveVar(0);
+ this.total = new ReactiveVar(0);
this.filter = new ReactiveVar('');
- this.ready = new ReactiveVar(false);
+ this.query = new ReactiveVar({});
+ this.isLoading = new ReactiveVar(false);
this.tabBar = new RocketChatTabBar();
this.tabBar.showGroup(FlowRouter.current().route.name);
@@ -90,27 +81,40 @@ Template.adminEmoji.onCreated(function() {
template: 'adminEmojiInfo',
order: 2,
});
-
- this.autorun(function() {
- const limit = instance.limit != null ? instance.limit.get() : 0;
- const subscription = instance.subscribe('fullEmojiData', '', limit);
- instance.ready.set(subscription.ready());
+ this.onSuccessCallback = () => {
+ this.offset.set(0);
+ return this.loadEmojis(this.query.get(), this.offset.get());
+ };
+ this.tabBarData.set({
+ onSuccess: instance.onSuccessCallback,
});
- this.customemoji = function() {
- const filter = instance.filter != null ? s.trim(instance.filter.get()) : '';
+ this.loadEmojis = _.debounce(async (query, offset) => {
+ this.isLoading.set(true);
+ const { emojis, total } = await APIClient.v1.get(`emoji-custom.all?count=${ LIST_SIZE }&offset=${ offset }&query=${ JSON.stringify(query) }`);
+ this.total.set(total);
+ if (offset === 0) {
+ this.emojis.set(emojis);
+ } else {
+ this.emojis.set(this.emojis.get().concat(emojis));
+ }
+ this.isLoading.set(false);
+ }, DEBOUNCE_TIME_TO_SEARCH_IN_MS);
- let query = {};
+ this.autorun(() => {
+ this.filter.get();
+ this.offset.set(0);
+ });
+ this.autorun(() => {
+ const filter = this.filter.get() && this.filter.get().trim();
+ const offset = this.offset.get();
if (filter) {
- const filterReg = new RegExp(s.escapeRegExp(filter), 'i');
- query = { $or: [{ name: filterReg }, { aliases: filterReg }] };
+ const regex = { $regex: filter, $options: 'i' };
+ return this.loadEmojis({ $or: [{ name: regex }, { aliases: regex }] }, offset);
}
-
- const limit = instance.limit != null ? instance.limit.get() : 0;
-
- return EmojiCustom.find(query, { limit, sort: { name: 1 } }).fetch();
- };
+ return this.loadEmojis({}, offset);
+ });
});
Template.adminEmoji.onRendered(() =>
diff --git a/app/emoji-custom/client/admin/emojiEdit.js b/app/emoji-custom/client/admin/emojiEdit.js
index 0247f8e12a7..30134afbd9e 100644
--- a/app/emoji-custom/client/admin/emojiEdit.js
+++ b/app/emoji-custom/client/admin/emojiEdit.js
@@ -58,6 +58,7 @@ Template.emojiEdit.onCreated(function() {
}
this.tabBar = Template.currentData().tabBar;
+ this.onSuccess = Template.currentData().onSuccess;
this.cancel = (form, name) => {
form.reset();
@@ -143,6 +144,7 @@ Template.emojiEdit.onCreated(function() {
} else {
toastr.success(t('Custom_Emoji_Added_Successfully'));
}
+ this.onSuccess();
this.cancel(form, emojiData.name);
}
diff --git a/app/emoji-custom/client/admin/emojiInfo.js b/app/emoji-custom/client/admin/emojiInfo.js
index cb84c0053b6..141dc2116c9 100644
--- a/app/emoji-custom/client/admin/emojiInfo.js
+++ b/app/emoji-custom/client/admin/emojiInfo.js
@@ -29,6 +29,7 @@ Template.emojiInfo.helpers({
return {
tabBar: this.tabBar,
emoji: instance.emoji.get(),
+ onSuccess: instance.onSuccess,
back(name) {
instance.editingEmoji.set();
@@ -76,6 +77,7 @@ Template.emojiInfo.events({
timer: 2000,
showConfirmButton: false,
});
+ instance.onSuccess();
instance.tabBar.close();
});
@@ -86,13 +88,13 @@ Template.emojiInfo.events({
'click .edit-emoji'(e, instance) {
e.stopPropagation();
e.preventDefault();
-
instance.editingEmoji.set(instance.emoji.get()._id);
},
});
Template.emojiInfo.onCreated(function() {
this.emoji = new ReactiveVar();
+ this.onSuccess = Template.currentData().onSuccess;
this.editingEmoji = new ReactiveVar();
@@ -108,7 +110,7 @@ Template.emojiInfo.onCreated(function() {
});
this.autorun(() => {
- const data = Template.currentData();
+ const data = Template.currentData().emoji;
const emoji = this.emoji.get();
if (emoji != null && emoji.name != null) {
this.loadedName.set(emoji.name);
@@ -118,7 +120,7 @@ Template.emojiInfo.onCreated(function() {
});
this.autorun(() => {
- const data = Template.currentData();
+ const data = Template.currentData().emoji;
this.emoji.set(data);
});
});
diff --git a/app/emoji-custom/server/publications/fullEmojiData.js b/app/emoji-custom/server/publications/fullEmojiData.js
index b2771a914ae..f0e0d91c0ad 100644
--- a/app/emoji-custom/server/publications/fullEmojiData.js
+++ b/app/emoji-custom/server/publications/fullEmojiData.js
@@ -4,6 +4,7 @@ import s from 'underscore.string';
import { EmojiCustom } from '../../../models';
Meteor.publish('fullEmojiData', function(filter, limit) {
+ console.warn('The publication "fullEmojiData" is deprecated and will be removed after version v3.0.0');
if (!this.userId) {
return this.ready();
}
diff --git a/app/models/server/raw/EmojiCustom.js b/app/models/server/raw/EmojiCustom.js
new file mode 100644
index 00000000000..80b81d41958
--- /dev/null
+++ b/app/models/server/raw/EmojiCustom.js
@@ -0,0 +1,5 @@
+import { BaseRaw } from './BaseRaw';
+
+export class EmojiCustomRaw extends BaseRaw {
+
+}
diff --git a/app/models/server/raw/index.js b/app/models/server/raw/index.js
index 575d5a09e05..0c925d8632e 100644
--- a/app/models/server/raw/index.js
+++ b/app/models/server/raw/index.js
@@ -28,6 +28,8 @@ import LivechatExternalMessagesModel from '../models/LivechatExternalMessages';
import { LivechatExternalMessageRaw } from './LivechatExternalMessages';
import LivechatVisitorsModel from '../models/LivechatVisitors';
import { LivechatVisitorsRaw } from './LivechatVisitors';
+import EmojiCustomModel from '../models/EmojiCustom';
+import { EmojiCustomRaw } from './EmojiCustom';
import WebdavAccountsModel from '../models/WebdavAccounts';
import { WebdavAccountsRaw } from './WebdavAccounts';
import OAuthAppsModel from '../models/OAuthApps';
@@ -54,6 +56,7 @@ export const LivechatRooms = new LivechatRoomsRaw(LivechatRoomsModel.model.rawCo
export const Messages = new MessagesRaw(MessagesModel.model.rawCollection());
export const LivechatExternalMessage = new LivechatExternalMessageRaw(LivechatExternalMessagesModel.model.rawCollection());
export const LivechatVisitors = new LivechatVisitorsRaw(LivechatVisitorsModel.model.rawCollection());
+export const EmojiCustom = new EmojiCustomRaw(EmojiCustomModel.model.rawCollection());
export const WebdavAccounts = new WebdavAccountsRaw(WebdavAccountsModel.model.rawCollection());
export const OAuthApps = new OAuthAppsRaw(OAuthAppsModel.model.rawCollection());
export const CustomSounds = new CustomSoundsRaw(CustomSoundsModel.model.rawCollection());
diff --git a/app/reactions/client/methods/setReaction.js b/app/reactions/client/methods/setReaction.js
index 285dd9ce18c..db58a8b4ea6 100644
--- a/app/reactions/client/methods/setReaction.js
+++ b/app/reactions/client/methods/setReaction.js
@@ -1,7 +1,7 @@
import { Meteor } from 'meteor/meteor';
import _ from 'underscore';
-import { Messages, Rooms, Subscriptions, EmojiCustom } from '../../../models';
+import { Messages, Rooms, Subscriptions } from '../../../models';
import { callbacks } from '../../../callbacks';
import { emoji } from '../../../emoji';
@@ -34,7 +34,7 @@ Meteor.methods({
return false;
}
- if (!emoji.list[reaction] && EmojiCustom.findByNameOrAlias(reaction).count() === 0) {
+ if (!emoji.list[reaction]) {
return false;
}
diff --git a/tests/end-to-end/api/12-emoji-custom.js b/tests/end-to-end/api/12-emoji-custom.js
index c91141a50d4..813ff2f979d 100644
--- a/tests/end-to-end/api/12-emoji-custom.js
+++ b/tests/end-to-end/api/12-emoji-custom.js
@@ -250,6 +250,22 @@ describe('[EmojiCustom]', function() {
});
});
+ describe('[/emoji-custom.all]', () => {
+ it('should return emojis', (done) => {
+ request.get(api('emoji-custom.all'))
+ .set(credentials)
+ .expect(200)
+ .expect((res) => {
+ expect(res.body).to.have.property('emojis').and.to.be.an('array');
+ expect(res.body).to.have.property('total');
+ expect(res.body).to.have.property('offset');
+ expect(res.body).to.have.property('count');
+ })
+ .end(done);
+ });
+ });
+
+
describe('[/emoji-custom.delete]', () => {
it('should throw an error when trying delete custom emoji without the required param "emojid"', (done) => {
request.post(api('emoji-custom.delete'))