This commit is contained in:
parent
aaa7a07849
commit
0610acbf6e
10 changed files with 134 additions and 41 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"author": "syuilo <i@syuilo.com>",
|
"author": "syuilo <i@syuilo.com>",
|
||||||
"version": "0.0.1340",
|
"version": "0.0.1395",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "A miniblog-based SNS",
|
"description": "A miniblog-based SNS",
|
||||||
"bugs": "https://github.com/syuilo/misskey/issues",
|
"bugs": "https://github.com/syuilo/misskey/issues",
|
||||||
|
|
|
@ -5,6 +5,7 @@ import $ from 'cafy';
|
||||||
import Vote from '../../../models/poll-vote';
|
import Vote from '../../../models/poll-vote';
|
||||||
import Post from '../../../models/post';
|
import Post from '../../../models/post';
|
||||||
import notify from '../../../common/notify';
|
import notify from '../../../common/notify';
|
||||||
|
import { publishPostStream } from '../../../event';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vote poll of a post
|
* Vote poll of a post
|
||||||
|
@ -62,11 +63,13 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
|
||||||
const inc = {};
|
const inc = {};
|
||||||
inc[`poll.choices.${findWithAttr(post.poll.choices, 'id', choice)}.votes`] = 1;
|
inc[`poll.choices.${findWithAttr(post.poll.choices, 'id', choice)}.votes`] = 1;
|
||||||
|
|
||||||
// Increment likes count
|
// Increment votes count
|
||||||
Post.update({ _id: post._id }, {
|
await Post.update({ _id: post._id }, {
|
||||||
$inc: inc
|
$inc: inc
|
||||||
});
|
});
|
||||||
|
|
||||||
|
publishPostStream(post._id, 'poll_voted');
|
||||||
|
|
||||||
// Notify
|
// Notify
|
||||||
notify(post.user_id, user._id, 'poll_vote', {
|
notify(post.user_id, user._id, 'poll_vote', {
|
||||||
post_id: post._id,
|
post_id: post._id,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import $ from 'cafy';
|
||||||
import Reaction from '../../../models/post-reaction';
|
import Reaction from '../../../models/post-reaction';
|
||||||
import Post from '../../../models/post';
|
import Post from '../../../models/post';
|
||||||
import notify from '../../../common/notify';
|
import notify from '../../../common/notify';
|
||||||
|
import { publishPostStream } from '../../../event';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* React to a post
|
* React to a post
|
||||||
|
@ -69,10 +70,12 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
|
||||||
inc['reaction_counts.' + reaction] = 1;
|
inc['reaction_counts.' + reaction] = 1;
|
||||||
|
|
||||||
// Increment reactions count
|
// Increment reactions count
|
||||||
Post.update({ _id: post._id }, {
|
await Post.update({ _id: post._id }, {
|
||||||
$inc: inc
|
$inc: inc
|
||||||
});
|
});
|
||||||
|
|
||||||
|
publishPostStream(post._id, 'reacted');
|
||||||
|
|
||||||
// Notify
|
// Notify
|
||||||
notify(post.user_id, user._id, 'reaction', {
|
notify(post.user_id, user._id, 'reaction', {
|
||||||
post_id: post._id,
|
post_id: post._id,
|
||||||
|
|
|
@ -25,6 +25,10 @@ class MisskeyEvent {
|
||||||
this.publish(`user-stream:${userId}`, type, typeof value === 'undefined' ? null : value);
|
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 {
|
public publishMessagingStream(userId: ID, otherpartyId: ID, type: string, value?: any): void {
|
||||||
this.publish(`messaging-stream:${userId}-${otherpartyId}`, type, typeof value === 'undefined' ? null : value);
|
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 default ev.publishUserStream.bind(ev);
|
||||||
|
|
||||||
|
export const publishPostStream = ev.publishPostStream.bind(ev);
|
||||||
|
|
||||||
export const publishMessagingStream = ev.publishMessagingStream.bind(ev);
|
export const publishMessagingStream = ev.publishMessagingStream.bind(ev);
|
||||||
|
|
|
@ -1,10 +1,46 @@
|
||||||
import * as websocket from 'websocket';
|
import * as websocket from 'websocket';
|
||||||
import * as redis from 'redis';
|
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 {
|
export default function homeStream(request: websocket.request, connection: websocket.connection, subscriber: redis.RedisClient, user: any): void {
|
||||||
// Subscribe Home stream channel
|
// Subscribe Home stream channel
|
||||||
subscriber.subscribe(`misskey:user-stream:${user._id}`);
|
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
|
const user = await User
|
||||||
.findOne({
|
.findOne({
|
||||||
token: token
|
token: token
|
||||||
}, {
|
|
||||||
fields: {
|
|
||||||
_id: true
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
resolve(user);
|
resolve(user);
|
||||||
|
|
|
@ -44,6 +44,10 @@ class Connection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
send(message) {
|
||||||
|
this.socket.send(JSON.stringify(message));
|
||||||
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
this.socket.removeEventListener('open', this.onOpen);
|
this.socket.removeEventListener('open', this.onOpen);
|
||||||
this.socket.removeEventListener('message', this.onMessage);
|
this.socket.removeEventListener('message', this.onMessage);
|
||||||
|
|
|
@ -70,11 +70,16 @@
|
||||||
<script>
|
<script>
|
||||||
this.mixin('api');
|
this.mixin('api');
|
||||||
|
|
||||||
this.post = this.opts.post;
|
this.init = post => {
|
||||||
this.poll = this.post.poll;
|
this.post = post;
|
||||||
this.total = this.poll.choices.reduce((a, b) => a + b.votes, 0);
|
this.poll = this.post.poll;
|
||||||
this.isVoted = this.poll.choices.some(c => c.is_voted);
|
this.total = this.poll.choices.reduce((a, b) => a + b.votes, 0);
|
||||||
this.result = this.isVoted;
|
this.isVoted = this.poll.choices.some(c => c.is_voted);
|
||||||
|
this.result = this.isVoted;
|
||||||
|
this.update();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.init(this.opts.post);
|
||||||
|
|
||||||
this.toggleResult = () => {
|
this.toggleResult = () => {
|
||||||
this.result = !this.result;
|
this.result = !this.result;
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
<div class="media" if={ p.media }>
|
<div class="media" if={ p.media }>
|
||||||
<mk-images-viewer images={ p.media }></mk-images-viewer>
|
<mk-images-viewer images={ p.media }></mk-images-viewer>
|
||||||
</div>
|
</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>
|
<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>
|
<mk-post-preview class="repost" post={ p.repost }></mk-post-preview>
|
||||||
</div>
|
</div>
|
||||||
|
@ -332,6 +332,7 @@
|
||||||
import dateStringify from '../../common/scripts/date-stringify';
|
import dateStringify from '../../common/scripts/date-stringify';
|
||||||
|
|
||||||
this.mixin('api');
|
this.mixin('api');
|
||||||
|
this.mixin('stream');
|
||||||
this.mixin('user-preview');
|
this.mixin('user-preview');
|
||||||
|
|
||||||
this.isDetailOpened = false;
|
this.isDetailOpened = false;
|
||||||
|
@ -347,19 +348,30 @@
|
||||||
|
|
||||||
this.set(this.opts.post);
|
this.set(this.opts.post);
|
||||||
|
|
||||||
this.refresh = () => {
|
this.refresh = post => {
|
||||||
this.api('posts/show', {
|
this.set(post);
|
||||||
post_id: this.post.id
|
this.update();
|
||||||
}).then(post => {
|
if (this.refs.reactionsViewer) this.refs.reactionsViewer.update({
|
||||||
this.set(post);
|
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.on('mount', () => {
|
||||||
|
this.stream.send({
|
||||||
|
type: 'capture',
|
||||||
|
id: this.p.id
|
||||||
|
});
|
||||||
|
|
||||||
|
this.stream.event.on('post-updated', this.onStreamPostUpdated);
|
||||||
|
|
||||||
if (this.p.text) {
|
if (this.p.text) {
|
||||||
const tokens = this.p.ast;
|
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 = () => {
|
this.reply = () => {
|
||||||
riot.mount(document.body.appendChild(document.createElement('mk-post-form-window')), {
|
riot.mount(document.body.appendChild(document.createElement('mk-post-form-window')), {
|
||||||
reply: this.p
|
reply: this.p
|
||||||
|
@ -395,8 +416,7 @@
|
||||||
this.react = () => {
|
this.react = () => {
|
||||||
riot.mount(document.body.appendChild(document.createElement('mk-reaction-picker')), {
|
riot.mount(document.body.appendChild(document.createElement('mk-reaction-picker')), {
|
||||||
source: this.refs.reactButton,
|
source: this.refs.reactButton,
|
||||||
post: this.p,
|
post: this.p
|
||||||
cb: this.refresh
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
<div class="media" if={ p.media }>
|
<div class="media" if={ p.media }>
|
||||||
<mk-images-viewer images={ p.media }></mk-images-viewer>
|
<mk-images-viewer images={ p.media }></mk-images-viewer>
|
||||||
</div>
|
</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>
|
<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>
|
<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>
|
<mk-post-preview class="repost" post={ p.repost }></mk-post-preview>
|
||||||
|
@ -306,12 +306,13 @@
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
this.mixin('api');
|
|
||||||
|
|
||||||
import compile from '../../common/scripts/text-compiler';
|
import compile from '../../common/scripts/text-compiler';
|
||||||
import getPostSummary from '../../common/scripts/get-post-summary';
|
import getPostSummary from '../../common/scripts/get-post-summary';
|
||||||
import openPostForm from '../scripts/open-post-form';
|
import openPostForm from '../scripts/open-post-form';
|
||||||
|
|
||||||
|
this.mixin('api');
|
||||||
|
this.mixin('stream');
|
||||||
|
|
||||||
this.set = post => {
|
this.set = post => {
|
||||||
this.post = post;
|
this.post = post;
|
||||||
this.isRepost = this.post.repost != null && this.post.text == null;
|
this.isRepost = this.post.repost != null && this.post.text == null;
|
||||||
|
@ -323,19 +324,30 @@
|
||||||
|
|
||||||
this.set(this.opts.post);
|
this.set(this.opts.post);
|
||||||
|
|
||||||
this.refresh = () => {
|
this.refresh = post => {
|
||||||
this.api('posts/show', {
|
this.set(post);
|
||||||
post_id: this.post.id
|
this.update();
|
||||||
}).then(post => {
|
if (this.refs.reactionsViewer) this.refs.reactionsViewer.update({
|
||||||
this.set(post);
|
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.on('mount', () => {
|
||||||
|
this.stream.send({
|
||||||
|
type: 'capture',
|
||||||
|
id: this.p.id
|
||||||
|
});
|
||||||
|
|
||||||
|
this.stream.event.on('post-updated', this.onStreamPostUpdated);
|
||||||
|
|
||||||
if (this.p.text) {
|
if (this.p.text) {
|
||||||
const tokens = this.p.ast;
|
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 = () => {
|
this.reply = () => {
|
||||||
openPostForm({
|
openPostForm({
|
||||||
reply: this.p
|
reply: this.p
|
||||||
|
@ -374,8 +395,7 @@
|
||||||
this.react = () => {
|
this.react = () => {
|
||||||
riot.mount(document.body.appendChild(document.createElement('mk-reaction-picker')), {
|
riot.mount(document.body.appendChild(document.createElement('mk-reaction-picker')), {
|
||||||
source: this.refs.reactButton,
|
source: this.refs.reactButton,
|
||||||
post: this.p,
|
post: this.p
|
||||||
cb: this.refresh
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in a new issue