From a6e7bbc306a93bd56bb1941e29d6fc474c9c36d5 Mon Sep 17 00:00:00 2001 From: MeiMei <30769358+mei23@users.noreply.github.com> Date: Thu, 31 Jan 2019 20:42:45 +0900 Subject: [PATCH] send/receive user hashtags via AP (#4064) --- src/models/user.ts | 1 + src/remote/activitypub/models/note.ts | 13 +------------ src/remote/activitypub/models/person.ts | 8 +++++++- src/remote/activitypub/models/tag.ts | 11 +++++++++++ src/remote/activitypub/renderer/person.ts | 4 ++++ src/server/api/endpoints/i/update.ts | 6 +++++- 6 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/models/user.ts b/src/models/user.ts index ab45efc981..ef091848f9 100644 --- a/src/models/user.ts +++ b/src/models/user.ts @@ -48,6 +48,7 @@ type IUserBase = { lang?: string; pinnedNoteIds: mongo.ObjectID[]; emojis?: string[]; + tags?: string[]; /** * 凍結されているか否か diff --git a/src/remote/activitypub/models/note.ts b/src/remote/activitypub/models/note.ts index 0f2e515260..1b61435aa2 100644 --- a/src/remote/activitypub/models/note.ts +++ b/src/remote/activitypub/models/note.ts @@ -11,7 +11,7 @@ import { resolveImage } from './image'; import { IRemoteUser, IUser } from '../../../models/user'; import { fromHtml } from '../../../mfm/fromHtml'; import Emoji, { IEmoji } from '../../../models/emoji'; -import { ITag } from './tag'; +import { ITag, extractHashtags } from './tag'; import { toUnicode } from 'punycode'; import { unique, concat, difference } from '../../../prelude/array'; import { extractPollFromQuestion } from './question'; @@ -239,14 +239,3 @@ async function extractMentionedUsers(actor: IRemoteUser, to: string[], cc: strin return users.filter(x => x != null); } - -function extractHashtags(tags: ITag[]) { - if (!tags) return []; - - const hashtags = tags.filter(tag => tag.type === 'Hashtag' && typeof tag.name == 'string'); - - return hashtags.map(tag => { - const m = tag.name.match(/^#(.+)/); - return m ? m[1] : null; - }).filter(x => x != null); -} diff --git a/src/remote/activitypub/models/person.ts b/src/remote/activitypub/models/person.ts index 54e57f7330..16f1086b86 100644 --- a/src/remote/activitypub/models/person.ts +++ b/src/remote/activitypub/models/person.ts @@ -17,7 +17,7 @@ import registerInstance from '../../../services/register-instance'; import Instance from '../../../models/instance'; import getDriveFileUrl from '../../../misc/get-drive-file-url'; import { IEmoji } from '../../../models/emoji'; -import { ITag } from './tag'; +import { ITag, extractHashtags } from './tag'; import Following from '../../../models/following'; import { IIdentifier } from './identifier'; @@ -140,6 +140,8 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise tag.type === 'Hashtag' && typeof tag.name == 'string'); + + return hashtags.map(tag => { + const m = tag.name.match(/^#(.+)/); + return m ? m[1] : null; + }).filter(x => x != null); +} diff --git a/src/remote/activitypub/renderer/person.ts b/src/remote/activitypub/renderer/person.ts index 68f0bd83fe..77e60cd61a 100644 --- a/src/remote/activitypub/renderer/person.ts +++ b/src/remote/activitypub/renderer/person.ts @@ -8,6 +8,7 @@ import DriveFile from '../../../models/drive-file'; import { getEmojis } from './note'; import renderEmoji from './emoji'; import { IIdentifier } from '../models/identifier'; +import renderHashtag from './hashtag'; export default async (user: ILocalUser) => { const id = `${config.url}/users/${user._id}`; @@ -67,8 +68,11 @@ export default async (user: ILocalUser) => { const emojis = await getEmojis(user.emojis); const apemojis = emojis.map(emoji => renderEmoji(emoji)); + const hashtagTags = (user.tags || []).map(tag => renderHashtag(tag)); + const tag = [ ...apemojis, + ...hashtagTags, ]; return { diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts index b47e29c5ad..4b02e393bf 100644 --- a/src/server/api/endpoints/i/update.ts +++ b/src/server/api/endpoints/i/update.ts @@ -8,6 +8,7 @@ import define from '../../define'; import getDriveFileUrl from '../../../../misc/get-drive-file-url'; import { parse, parsePlain } from '../../../../mfm/parse'; import extractEmojis from '../../../../misc/extract-emojis'; +import extractHashtags from '../../../../misc/extract-hashtags'; const langmap = require('langmap'); export const meta = { @@ -201,9 +202,10 @@ export default define(meta, (ps, user, app) => new Promise(async (res, rej) => { } } - //#region emojis + //#region emojis/tags if (updates.name != null || updates.description != null) { let emojis = [] as string[]; + let tags = [] as string[]; if (updates.name != null) { const tokens = parsePlain(updates.name); @@ -213,9 +215,11 @@ export default define(meta, (ps, user, app) => new Promise(async (res, rej) => { if (updates.description != null) { const tokens = parse(updates.description); emojis = emojis.concat(extractEmojis(tokens)); + tags = extractHashtags(tokens); } updates.emojis = emojis; + updates.tags = tags; } //#endregion