This commit is contained in:
		
							parent
							
								
									aaa7a07849
								
							
						
					
					
						commit
						0610acbf6e
					
				
					 10 changed files with 134 additions and 41 deletions
				
			
		| 
						 | 
				
			
			@ -5,6 +5,7 @@ import $ from 'cafy';
 | 
			
		|||
import Vote from '../../../models/poll-vote';
 | 
			
		||||
import Post from '../../../models/post';
 | 
			
		||||
import notify from '../../../common/notify';
 | 
			
		||||
import { publishPostStream } from '../../../event';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Vote poll of a post
 | 
			
		||||
| 
						 | 
				
			
			@ -62,11 +63,13 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 | 
			
		|||
	const inc = {};
 | 
			
		||||
	inc[`poll.choices.${findWithAttr(post.poll.choices, 'id', choice)}.votes`] = 1;
 | 
			
		||||
 | 
			
		||||
	// Increment likes count
 | 
			
		||||
	Post.update({ _id: post._id }, {
 | 
			
		||||
	// Increment votes count
 | 
			
		||||
	await Post.update({ _id: post._id }, {
 | 
			
		||||
		$inc: inc
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	publishPostStream(post._id, 'poll_voted');
 | 
			
		||||
 | 
			
		||||
	// Notify
 | 
			
		||||
	notify(post.user_id, user._id, 'poll_vote', {
 | 
			
		||||
		post_id: post._id,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ import $ from 'cafy';
 | 
			
		|||
import Reaction from '../../../models/post-reaction';
 | 
			
		||||
import Post from '../../../models/post';
 | 
			
		||||
import notify from '../../../common/notify';
 | 
			
		||||
import { publishPostStream } from '../../../event';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * React to a post
 | 
			
		||||
| 
						 | 
				
			
			@ -69,10 +70,12 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 | 
			
		|||
	inc['reaction_counts.' + reaction] = 1;
 | 
			
		||||
 | 
			
		||||
	// Increment reactions count
 | 
			
		||||
	Post.update({ _id: post._id }, {
 | 
			
		||||
	await Post.update({ _id: post._id }, {
 | 
			
		||||
		$inc: inc
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	publishPostStream(post._id, 'reacted');
 | 
			
		||||
 | 
			
		||||
	// Notify
 | 
			
		||||
	notify(post.user_id, user._id, 'reaction', {
 | 
			
		||||
		post_id: post._id,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,10 @@ class MisskeyEvent {
 | 
			
		|||
		this.publish(`user-stream:${userId}`, type, typeof value === 'undefined' ? null : value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public publishPostStream(postId: ID, type: string, value?: any): void {
 | 
			
		||||
		this.publish(`post-stream:${postId}`, type, typeof value === 'undefined' ? null : value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public publishMessagingStream(userId: ID, otherpartyId: ID, type: string, value?: any): void {
 | 
			
		||||
		this.publish(`messaging-stream:${userId}-${otherpartyId}`, type, typeof value === 'undefined' ? null : value);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -34,4 +38,6 @@ const ev = new MisskeyEvent();
 | 
			
		|||
 | 
			
		||||
export default ev.publishUserStream.bind(ev);
 | 
			
		||||
 | 
			
		||||
export const publishPostStream = ev.publishPostStream.bind(ev);
 | 
			
		||||
 | 
			
		||||
export const publishMessagingStream = ev.publishMessagingStream.bind(ev);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,46 @@
 | 
			
		|||
import * as websocket from 'websocket';
 | 
			
		||||
import * as redis from 'redis';
 | 
			
		||||
import * as debug from 'debug';
 | 
			
		||||
 | 
			
		||||
import serializePost from '../serializers/post';
 | 
			
		||||
 | 
			
		||||
const log = debug('misskey');
 | 
			
		||||
 | 
			
		||||
export default function homeStream(request: websocket.request, connection: websocket.connection, subscriber: redis.RedisClient, user: any): void {
 | 
			
		||||
	// Subscribe Home stream channel
 | 
			
		||||
	subscriber.subscribe(`misskey:user-stream:${user._id}`);
 | 
			
		||||
	subscriber.on('message', (_, data) => {
 | 
			
		||||
		connection.send(data);
 | 
			
		||||
 | 
			
		||||
	subscriber.on('message', async (channel, data) => {
 | 
			
		||||
		switch (channel.split(':')[1]) {
 | 
			
		||||
			case 'user-stream':
 | 
			
		||||
				connection.send(data);
 | 
			
		||||
				break;
 | 
			
		||||
			case 'post-stream':
 | 
			
		||||
				const postId = channel.split(':')[2];
 | 
			
		||||
				log(`RECEIVED: ${postId} ${data} by @${user.username}`);
 | 
			
		||||
				const post = await serializePost(postId, user, {
 | 
			
		||||
					detail: true
 | 
			
		||||
				});
 | 
			
		||||
				connection.send(JSON.stringify({
 | 
			
		||||
					type: 'post-updated',
 | 
			
		||||
					body: {
 | 
			
		||||
						post: post
 | 
			
		||||
					}
 | 
			
		||||
				}));
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	connection.on('message', data => {
 | 
			
		||||
		const msg = JSON.parse(data.utf8Data);
 | 
			
		||||
 | 
			
		||||
		switch (msg.type) {
 | 
			
		||||
			case 'capture':
 | 
			
		||||
					if (!msg.id) return;
 | 
			
		||||
					const postId = msg.id;
 | 
			
		||||
					log(`CAPTURE: ${postId} by @${user.username}`);
 | 
			
		||||
					subscriber.subscribe(`misskey:post-stream:${postId}`);
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,10 +62,6 @@ function authenticate(connection: websocket.connection, token: string): Promise<
 | 
			
		|||
			const user = await User
 | 
			
		||||
				.findOne({
 | 
			
		||||
					token: token
 | 
			
		||||
				}, {
 | 
			
		||||
					fields: {
 | 
			
		||||
						_id: true
 | 
			
		||||
					}
 | 
			
		||||
				});
 | 
			
		||||
 | 
			
		||||
			resolve(user);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,6 +44,10 @@ class Connection {
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	send(message) {
 | 
			
		||||
		this.socket.send(JSON.stringify(message));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	close() {
 | 
			
		||||
		this.socket.removeEventListener('open', this.onOpen);
 | 
			
		||||
		this.socket.removeEventListener('message', this.onMessage);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,11 +70,16 @@
 | 
			
		|||
	<script>
 | 
			
		||||
		this.mixin('api');
 | 
			
		||||
 | 
			
		||||
		this.post = this.opts.post;
 | 
			
		||||
		this.poll = this.post.poll;
 | 
			
		||||
		this.total = this.poll.choices.reduce((a, b) => a + b.votes, 0);
 | 
			
		||||
		this.isVoted = this.poll.choices.some(c => c.is_voted);
 | 
			
		||||
		this.result = this.isVoted;
 | 
			
		||||
		this.init = post => {
 | 
			
		||||
			this.post = post;
 | 
			
		||||
			this.poll = this.post.poll;
 | 
			
		||||
			this.total = this.poll.choices.reduce((a, b) => a + b.votes, 0);
 | 
			
		||||
			this.isVoted = this.poll.choices.some(c => c.is_voted);
 | 
			
		||||
			this.result = this.isVoted;
 | 
			
		||||
			this.update();
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		this.init(this.opts.post);
 | 
			
		||||
 | 
			
		||||
		this.toggleResult = () => {
 | 
			
		||||
			this.result = !this.result;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,7 +40,7 @@
 | 
			
		|||
				<div class="media" if={ p.media }>
 | 
			
		||||
					<mk-images-viewer images={ p.media }></mk-images-viewer>
 | 
			
		||||
				</div>
 | 
			
		||||
				<mk-poll if={ p.poll } post={ p }></mk-poll>
 | 
			
		||||
				<mk-poll if={ p.poll } post={ p } ref="pollViewer"></mk-poll>
 | 
			
		||||
				<div class="repost" if={ p.repost }><i class="fa fa-quote-right fa-flip-horizontal"></i>
 | 
			
		||||
					<mk-post-preview class="repost" post={ p.repost }></mk-post-preview>
 | 
			
		||||
				</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -332,6 +332,7 @@
 | 
			
		|||
		import dateStringify from '../../common/scripts/date-stringify';
 | 
			
		||||
 | 
			
		||||
		this.mixin('api');
 | 
			
		||||
		this.mixin('stream');
 | 
			
		||||
		this.mixin('user-preview');
 | 
			
		||||
 | 
			
		||||
		this.isDetailOpened = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -347,19 +348,30 @@
 | 
			
		|||
 | 
			
		||||
		this.set(this.opts.post);
 | 
			
		||||
 | 
			
		||||
		this.refresh = () => {
 | 
			
		||||
			this.api('posts/show', {
 | 
			
		||||
				post_id: this.post.id
 | 
			
		||||
			}).then(post => {
 | 
			
		||||
				this.set(post);
 | 
			
		||||
				this.update();
 | 
			
		||||
				if (this.refs.reactionsViewer) this.refs.reactionsViewer.update({
 | 
			
		||||
					post
 | 
			
		||||
				});
 | 
			
		||||
		this.refresh = post => {
 | 
			
		||||
			this.set(post);
 | 
			
		||||
			this.update();
 | 
			
		||||
			if (this.refs.reactionsViewer) this.refs.reactionsViewer.update({
 | 
			
		||||
				post
 | 
			
		||||
			});
 | 
			
		||||
			if (this.refs.pollViewer) this.refs.pollViewer.init(post);
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		this.onStreamPostUpdated = data => {
 | 
			
		||||
			const post = data.post;
 | 
			
		||||
			if (post.id == this.p.id) {
 | 
			
		||||
				this.refresh(post);
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		this.on('mount', () => {
 | 
			
		||||
			this.stream.send({
 | 
			
		||||
				type: 'capture',
 | 
			
		||||
				id: this.p.id
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.stream.event.on('post-updated', this.onStreamPostUpdated);
 | 
			
		||||
 | 
			
		||||
			if (this.p.text) {
 | 
			
		||||
				const tokens = this.p.ast;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -380,6 +392,15 @@
 | 
			
		|||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		this.on('unmount', () => {
 | 
			
		||||
			this.stream.send({
 | 
			
		||||
				type: 'decapture',
 | 
			
		||||
				id: this.p.id
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.stream.event.off('post-updated', this.onStreamPostUpdated);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		this.reply = () => {
 | 
			
		||||
			riot.mount(document.body.appendChild(document.createElement('mk-post-form-window')), {
 | 
			
		||||
				reply: this.p
 | 
			
		||||
| 
						 | 
				
			
			@ -395,8 +416,7 @@
 | 
			
		|||
		this.react = () => {
 | 
			
		||||
			riot.mount(document.body.appendChild(document.createElement('mk-reaction-picker')), {
 | 
			
		||||
				source: this.refs.reactButton,
 | 
			
		||||
				post: this.p,
 | 
			
		||||
				cb: this.refresh
 | 
			
		||||
				post: this.p
 | 
			
		||||
			});
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,7 @@
 | 
			
		|||
				<div class="media" if={ p.media }>
 | 
			
		||||
					<mk-images-viewer images={ p.media }></mk-images-viewer>
 | 
			
		||||
				</div>
 | 
			
		||||
				<mk-poll if={ p.poll } post={ p }></mk-poll>
 | 
			
		||||
				<mk-poll if={ p.poll } post={ p } ref="pollViewer"></mk-poll>
 | 
			
		||||
				<span class="app" if={ p.app }>via <b>{ p.app.name }</b></span>
 | 
			
		||||
				<div class="repost" if={ p.repost }><i class="fa fa-quote-right fa-flip-horizontal"></i>
 | 
			
		||||
					<mk-post-preview class="repost" post={ p.repost }></mk-post-preview>
 | 
			
		||||
| 
						 | 
				
			
			@ -306,12 +306,13 @@
 | 
			
		|||
 | 
			
		||||
	</style>
 | 
			
		||||
	<script>
 | 
			
		||||
		this.mixin('api');
 | 
			
		||||
 | 
			
		||||
		import compile from '../../common/scripts/text-compiler';
 | 
			
		||||
		import getPostSummary from '../../common/scripts/get-post-summary';
 | 
			
		||||
		import openPostForm from '../scripts/open-post-form';
 | 
			
		||||
 | 
			
		||||
		this.mixin('api');
 | 
			
		||||
		this.mixin('stream');
 | 
			
		||||
 | 
			
		||||
		this.set = post => {
 | 
			
		||||
			this.post = post;
 | 
			
		||||
			this.isRepost = this.post.repost != null && this.post.text == null;
 | 
			
		||||
| 
						 | 
				
			
			@ -323,19 +324,30 @@
 | 
			
		|||
 | 
			
		||||
		this.set(this.opts.post);
 | 
			
		||||
 | 
			
		||||
		this.refresh = () => {
 | 
			
		||||
			this.api('posts/show', {
 | 
			
		||||
				post_id: this.post.id
 | 
			
		||||
			}).then(post => {
 | 
			
		||||
				this.set(post);
 | 
			
		||||
				this.update();
 | 
			
		||||
				if (this.refs.reactionsViewer) this.refs.reactionsViewer.update({
 | 
			
		||||
					post
 | 
			
		||||
				});
 | 
			
		||||
		this.refresh = post => {
 | 
			
		||||
			this.set(post);
 | 
			
		||||
			this.update();
 | 
			
		||||
			if (this.refs.reactionsViewer) this.refs.reactionsViewer.update({
 | 
			
		||||
				post
 | 
			
		||||
			});
 | 
			
		||||
			if (this.refs.pollViewer) this.refs.pollViewer.init(post);
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		this.onStreamPostUpdated = data => {
 | 
			
		||||
			const post = data.post;
 | 
			
		||||
			if (post.id == this.p.id) {
 | 
			
		||||
				this.refresh(post);
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		this.on('mount', () => {
 | 
			
		||||
			this.stream.send({
 | 
			
		||||
				type: 'capture',
 | 
			
		||||
				id: this.p.id
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.stream.event.on('post-updated', this.onStreamPostUpdated);
 | 
			
		||||
 | 
			
		||||
			if (this.p.text) {
 | 
			
		||||
				const tokens = this.p.ast;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -356,6 +368,15 @@
 | 
			
		|||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		this.on('unmount', () => {
 | 
			
		||||
			this.stream.send({
 | 
			
		||||
				type: 'decapture',
 | 
			
		||||
				id: this.p.id
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.stream.event.off('post-updated', this.onStreamPostUpdated);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		this.reply = () => {
 | 
			
		||||
			openPostForm({
 | 
			
		||||
				reply: this.p
 | 
			
		||||
| 
						 | 
				
			
			@ -374,8 +395,7 @@
 | 
			
		|||
		this.react = () => {
 | 
			
		||||
			riot.mount(document.body.appendChild(document.createElement('mk-reaction-picker')), {
 | 
			
		||||
				source: this.refs.reactButton,
 | 
			
		||||
				post: this.p,
 | 
			
		||||
				cb: this.refresh
 | 
			
		||||
				post: this.p
 | 
			
		||||
			});
 | 
			
		||||
		};
 | 
			
		||||
	</script>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue