imports/model/server/publications.js
import { Instance } from '../instance';
import { Users } from '../users';
import { Threads } from '../threads';
import { ThreadUsers } from '../thread-users';
import { Files } from '/imports/files/server/files';
Meteor.publish('instance', function() {
if (!this.userId) {
return this.ready();
}
let user = Users.findOne(this.userId);
if (user.isAdmin()) {
return [
Instance.find({}),
Threads.find({category: 'Account', userId: this.userId})
];
} else {
return [
Instance.find({}, {fields: {domain: 1, company: 1, adminId: 1, sharedId: 1, "modules.email.type": 1, "modules.storage.type": 1}}),
Threads.find({category: 'Account', userId: this.userId})
];
}
});
Meteor.publish('counters', function() {
if (!this.userId) {
return this.ready();
}
Counts.publish(this, 'count-unread-inbox', ThreadUsers.find({
scope: 'private',
userType: 'Users',
userId: this.userId,
archive: {$ne: true},
spam: {$ne: true},
read: false
}));
Counts.publish(this, 'count-star', ThreadUsers.find({
userType: 'Users',
userId: this.userId,
star: true
}));
Counts.publish(this, 'count-archive', ThreadUsers.find({
userType: 'Users',
userId: this.userId,
archive: true
}));
Counts.publish(this, 'count-spam', ThreadUsers.find({
userType: 'Users',
userId: this.userId,
spam: true
}));
Counts.publish(this, 'count-spam-unread', ThreadUsers.find({
userType: 'Users',
userId: this.userId,
spam: true,
read: false
}));
ChannelUsers.find({userId: this.userId}).forEach((cu) => {
Counts.publish(this, `count-unread-channel-${cu.channelId}`, ThreadUsers.find({
userType: 'Channels',
userId: cu.channelId,
archive: {$ne: true},
read: false
}));
});
Counts.publish(this, 'count-mailgun-error', MailgunEmails.find({parsedAt: {$exists: false}}));
return this.ready();
});
const MIN_THREADS = 20;
const MAX_THREADS = 200;
Meteor.publishComposite("threads", function(options) {
check(options, Match.Maybe({
category: Match.Maybe(String),
limit: Match.Maybe(Number)
}));
let conditions = {scope: 'private', userType: 'Users', userId: this.userId, archive: {$ne: true}, spam: {$ne: true}};
let category = options && options.category;
if (category) {
_.extend(conditions, {category});
}
let limit = options && options.limit || MIN_THREADS;
let countName = category ? `threads.${category}` : 'threads';
Counts.publish(this, countName, ThreadUsers.find(conditions, {sort: {updatedAt: -1}}));
return {
find() {
return ThreadUsers.find(conditions, {
sort: {updatedAt: -1},
limit: Math.min(limit, MAX_THREADS)
});
},
children: [
{
find(tu) {
return Threads.find({_id: tu.threadId}, {
transform: (doc) => {
doc.read = tu.read;
doc.archive = tu.archive;
doc.star = tu.star;
doc.spam = tu.spam;
doc.params = tu.params;
return doc;
}
});
},
children: [
{
find(thread) {
return Messages.find({_id: thread.lastMessageId});
},
children: [
{
find(message) {
return Users.find({_id: message.userId});
}
}
]
}
]
}
]
};
});
Meteor.publishComposite("thread", function(threadId) {
check(threadId, String);
return {
find() {
return ThreadUsers.find({threadId, userType: 'Users', userId: this.userId});
},
children: [
{
find(tu) {
return Threads.find({_id: threadId}, {
transform: (doc) => {
doc.read = tu.read;
doc.archive = tu.archive;
doc.archiveAt = tu.archiveAt;
doc.star = tu.star;
doc.spam = tu.spam;
doc.params = tu.params;
return doc;
}
});
}
},
{
find(tu) {
return ThreadUsers.find({threadId}, {fields: {read: 0}});
}
}
]
};
});
const MIN_MESSAGES = 20;
const MAX_MESSAGES = 1000;
Meteor.publishComposite("thread.messages", function(threadId, options) {
check(threadId, String);
check(options, {
limit: Match.Maybe(Number)
});
let limit = options && options.limit || MIN_MESSAGES;
let countName = `messages.${threadId}`;
Counts.publish(this, countName, Messages.find({threadId}));
return {
find() {
return Messages.find({threadId}, {
sort: {createdAt: -1},
limit: Math.min(limit, MAX_MESSAGES)
});
},
children: [
{
find(message) {
return message.fileIds && Files.find({_id: {$in: message.fileIds}}).cursor;
}
},
{
find(message) {
return message.inlineFileIds && Files.find({_id: {$in: message.inlineFileIds}}).cursor;
}
}
]
};
});
Meteor.publishComposite("thread.messages.pin", function(threadId, options) {
check(threadId, String);
check(options, Match.Maybe({
limit: Match.Maybe(Number)
}));
let conditions = {threadId, pinAt: {$exists: true}};
let limit = options && options.limit || MIN_MESSAGES;
let countName = `messages.pin.${threadId}`;
Counts.publish(this, countName, Messages.find(conditions));
return {
find() {
return Messages.find(conditions, {
sort: {createdAt: -1},
limit: Math.min(limit, MAX_MESSAGES)
});
},
children: [
{
find(message) {
return message.fileIds && Files.find({_id: {$in: message.fileIds}}).cursor;
}
},
{
find(message) {
return message.inlineFileIds && Files.find({_id: {$in: message.inlineFileIds}}).cursor;
}
}
]
};
});
Meteor.publish("roster", function() {
return Users.find({"profile.type": 'Users'}, {fields: {emails: 1, profile: 1}});
});
Meteor.publish("contacts", function() {
return Users.find({"profile.type": 'Contacts'}, {fields: {emails: 1, profile: 1}});
});