ハッシュタグタイムラインを実装
This commit is contained in:
@ -13,12 +13,18 @@ export const meta = {
|
||||
},
|
||||
|
||||
params: {
|
||||
tag: $.str.note({
|
||||
tag: $.str.optional.note({
|
||||
desc: {
|
||||
'ja-JP': 'タグ'
|
||||
}
|
||||
}),
|
||||
|
||||
query: $.arr($.arr($.str)).optional.note({
|
||||
desc: {
|
||||
'ja-JP': 'クエリ'
|
||||
}
|
||||
}),
|
||||
|
||||
includeUserIds: $.arr($.type(ID)).optional.note({
|
||||
default: []
|
||||
}),
|
||||
@ -59,11 +65,9 @@ export const meta = {
|
||||
}
|
||||
}),
|
||||
|
||||
withFiles: $.bool.optional.nullable.note({
|
||||
default: null,
|
||||
|
||||
withFiles: $.bool.optional.note({
|
||||
desc: {
|
||||
'ja-JP': 'ファイルが添付された投稿に限定するか否か'
|
||||
'ja-JP': 'true にすると、ファイルが添付された投稿だけ取得します'
|
||||
}
|
||||
}),
|
||||
|
||||
@ -126,8 +130,14 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
|
||||
}
|
||||
|
||||
const q: any = {
|
||||
$and: [{
|
||||
$and: [ps.tag ? {
|
||||
tagsLower: ps.tag.toLowerCase()
|
||||
} : {
|
||||
$or: ps.query.map(tags => ({
|
||||
$and: tags.map(t => ({
|
||||
tagsLower: t.toLowerCase()
|
||||
}))
|
||||
}))
|
||||
}],
|
||||
deletedAt: { $exists: false }
|
||||
};
|
||||
@ -281,25 +291,10 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
|
||||
|
||||
const withFiles = ps.withFiles != null ? ps.withFiles : ps.media;
|
||||
|
||||
if (withFiles != null) {
|
||||
if (withFiles) {
|
||||
push({
|
||||
fileIds: {
|
||||
$exists: true,
|
||||
$ne: null
|
||||
}
|
||||
});
|
||||
} else {
|
||||
push({
|
||||
$or: [{
|
||||
fileIds: {
|
||||
$exists: false
|
||||
}
|
||||
}, {
|
||||
fileIds: null
|
||||
}]
|
||||
});
|
||||
}
|
||||
if (withFiles) {
|
||||
push({
|
||||
fileIds: { $exists: true, $ne: [] }
|
||||
});
|
||||
}
|
||||
|
||||
if (ps.poll != null) {
|
||||
|
48
src/server/api/stream/hashtag.ts
Normal file
48
src/server/api/stream/hashtag.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import * as websocket from 'websocket';
|
||||
import Xev from 'xev';
|
||||
|
||||
import { IUser } from '../../../models/user';
|
||||
import Mute from '../../../models/mute';
|
||||
import { pack } from '../../../models/note';
|
||||
|
||||
export default async function(
|
||||
request: websocket.request,
|
||||
connection: websocket.connection,
|
||||
subscriber: Xev,
|
||||
user?: IUser
|
||||
) {
|
||||
const mute = user ? await Mute.find({ muterId: user._id }) : null;
|
||||
const mutedUserIds = mute ? mute.map(m => m.muteeId.toString()) : [];
|
||||
|
||||
const q: Array<string[]> = JSON.parse((request.resourceURL.query as any).q);
|
||||
|
||||
// Subscribe stream
|
||||
subscriber.on('hashtag', async note => {
|
||||
const matched = q.some(tags => tags.every(tag => note.tags.map((t: string) => t.toLowerCase()).includes(tag.toLowerCase())));
|
||||
if (!matched) return;
|
||||
|
||||
// Renoteなら再pack
|
||||
if (note.renoteId != null) {
|
||||
note.renote = await pack(note.renoteId, user, {
|
||||
detail: true
|
||||
});
|
||||
}
|
||||
|
||||
//#region 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
|
||||
if (mutedUserIds.indexOf(note.userId) != -1) {
|
||||
return;
|
||||
}
|
||||
if (note.reply != null && mutedUserIds.indexOf(note.reply.userId) != -1) {
|
||||
return;
|
||||
}
|
||||
if (note.renote != null && mutedUserIds.indexOf(note.renote.userId) != -1) {
|
||||
return;
|
||||
}
|
||||
//#endregion
|
||||
|
||||
connection.send(JSON.stringify({
|
||||
type: 'note',
|
||||
body: note
|
||||
}));
|
||||
});
|
||||
}
|
@ -14,6 +14,7 @@ import reversiGameStream from './stream/games/reversi-game';
|
||||
import reversiStream from './stream/games/reversi';
|
||||
import serverStatsStream from './stream/server-stats';
|
||||
import notesStatsStream from './stream/notes-stats';
|
||||
import hashtagStream from './stream/hashtag';
|
||||
import { ParsedUrlQuery } from 'querystring';
|
||||
import authenticate from './authenticate';
|
||||
|
||||
@ -57,6 +58,11 @@ module.exports = (server: http.Server) => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (request.resourceURL.pathname === '/hashtag') {
|
||||
hashtagStream(request, connection, ev, user);
|
||||
return;
|
||||
}
|
||||
|
||||
if (user == null) {
|
||||
connection.send('authentication-failed');
|
||||
connection.close();
|
||||
|
Reference in New Issue
Block a user