Websocket Support (#937)
* Atom / RSS meta link * Spike * Feeling good about this spike now * Remove document.collection * Remove koa.ctx from all presenters to make them portable outside requests * Remove full serialized model from events Move events.add to controllers for now, will eventually be in commands * collections.create event parentDocument -> parentDocumentId * Fix up deprecated tests * Fixed: Doc creation * documents.move * Handle collection deleted * 💚 * Authorize room join requests * Move starred data structure Account for documents with no context on sockets * Add socket.io-redis * Add WEBSOCKETS_ENABLED env variable to disable websockets entirely for self hosted New installations will default to true, existing installations to false * 💚 No need for promise response here * Reload notice
This commit is contained in:
@@ -17,7 +17,7 @@ export default class Notifications {
|
||||
}
|
||||
|
||||
async documentUpdated(event: Event) {
|
||||
const document = await Document.findById(event.model.id);
|
||||
const document = await Document.findById(event.modelId);
|
||||
if (!document) return;
|
||||
|
||||
const { collection } = document;
|
||||
@@ -67,7 +67,7 @@ export default class Notifications {
|
||||
}
|
||||
|
||||
async collectionCreated(event: Event) {
|
||||
const collection = await Collection.findById(event.model.id, {
|
||||
const collection = await Collection.findById(event.modelId, {
|
||||
include: [
|
||||
{
|
||||
model: User,
|
||||
|
||||
@@ -18,7 +18,7 @@ export default class Slack {
|
||||
async integrationCreated(event: Event) {
|
||||
const integration = await Integration.findOne({
|
||||
where: {
|
||||
id: event.model.id,
|
||||
id: event.modelId,
|
||||
service: 'slack',
|
||||
type: 'post',
|
||||
},
|
||||
@@ -57,9 +57,12 @@ export default class Slack {
|
||||
}
|
||||
|
||||
async documentUpdated(event: Event) {
|
||||
const document = await Document.findById(event.model.id);
|
||||
const document = await Document.findById(event.modelId);
|
||||
if (!document) return;
|
||||
|
||||
// never send information on draft documents
|
||||
if (!document.publishedAt) return;
|
||||
|
||||
const integration = await Integration.findOne({
|
||||
where: {
|
||||
teamId: document.teamId,
|
||||
|
||||
115
server/services/websockets.js
Normal file
115
server/services/websockets.js
Normal file
@@ -0,0 +1,115 @@
|
||||
// @flow
|
||||
import type { Event } from '../events';
|
||||
import { Document, Collection } from '../models';
|
||||
import { presentDocument, presentCollection } from '../presenters';
|
||||
import { socketio } from '../';
|
||||
|
||||
export default class Websockets {
|
||||
async on(event: Event) {
|
||||
if (process.env.WEBSOCKETS_ENABLED !== 'true' || !socketio) return;
|
||||
|
||||
switch (event.name) {
|
||||
case 'documents.publish':
|
||||
case 'documents.restore':
|
||||
case 'documents.archive':
|
||||
case 'documents.unarchive':
|
||||
case 'documents.pin':
|
||||
case 'documents.unpin':
|
||||
case 'documents.update':
|
||||
case 'documents.delete': {
|
||||
const document = await Document.findById(event.modelId, {
|
||||
paranoid: false,
|
||||
});
|
||||
|
||||
return socketio.to(document.collectionId).emit('entities', {
|
||||
event: event.name,
|
||||
documents: [await presentDocument(document)],
|
||||
collections: [await presentCollection(document.collection)],
|
||||
});
|
||||
}
|
||||
case 'documents.create': {
|
||||
const document = await Document.findById(event.modelId);
|
||||
|
||||
return socketio.to(event.actorId).emit('entities', {
|
||||
event: event.name,
|
||||
documents: [await presentDocument(document)],
|
||||
collections: [await presentCollection(document.collection)],
|
||||
});
|
||||
}
|
||||
case 'documents.star':
|
||||
case 'documents.unstar': {
|
||||
return socketio.to(event.actorId).emit(event.name, {
|
||||
documentId: event.modelId,
|
||||
});
|
||||
}
|
||||
case 'documents.move': {
|
||||
const documents = await Document.findAll({
|
||||
where: {
|
||||
id: event.documentIds,
|
||||
},
|
||||
paranoid: false,
|
||||
});
|
||||
const collections = await Collection.findAll({
|
||||
where: {
|
||||
id: event.collectionIds,
|
||||
},
|
||||
paranoid: false,
|
||||
});
|
||||
documents.forEach(async document => {
|
||||
socketio.to(document.collectionId).emit('entities', {
|
||||
event: event.name,
|
||||
documents: [await presentDocument(document)],
|
||||
});
|
||||
});
|
||||
collections.forEach(async collection => {
|
||||
socketio.to(collection.id).emit('entities', {
|
||||
event: event.name,
|
||||
collections: [await presentCollection(collection)],
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
case 'collections.create': {
|
||||
const collection = await Collection.findById(event.modelId, {
|
||||
paranoid: false,
|
||||
});
|
||||
|
||||
socketio
|
||||
.to(collection.private ? collection.id : collection.teamId)
|
||||
.emit('entities', {
|
||||
event: event.name,
|
||||
collections: [await presentCollection(collection)],
|
||||
});
|
||||
return socketio
|
||||
.to(collection.private ? collection.id : collection.teamId)
|
||||
.emit('join', {
|
||||
event: event.name,
|
||||
roomId: collection.id,
|
||||
});
|
||||
}
|
||||
case 'collections.update':
|
||||
case 'collections.delete': {
|
||||
const collection = await Collection.findById(event.modelId, {
|
||||
paranoid: false,
|
||||
});
|
||||
|
||||
return socketio.to(collection.id).emit('entities', {
|
||||
event: event.name,
|
||||
collections: [await presentCollection(collection)],
|
||||
});
|
||||
}
|
||||
case 'collections.add_user':
|
||||
return socketio.to(event.modelId).emit('join', {
|
||||
event: event.name,
|
||||
roomId: event.collectionId,
|
||||
});
|
||||
case 'collections.remove_user':
|
||||
return socketio.to(event.modelId).emit('leave', {
|
||||
event: event.name,
|
||||
roomId: event.collectionId,
|
||||
});
|
||||
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user