mirror of
https://codeberg.org/yeentown/barkey.git
synced 2025-07-07 20:44:34 +00:00
View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/1098 Closes #1097 and #1098 Approved-by: dakkar <dakkar@thenautilus.net> Approved-by: Marie <github@yuugi.dev>
This commit is contained in:
commit
ae7767cd73
4 changed files with 70 additions and 11 deletions
|
@ -34,7 +34,7 @@ import { UtilityService } from '@/core/UtilityService.js';
|
||||||
import { JsonLdService } from './JsonLdService.js';
|
import { JsonLdService } from './JsonLdService.js';
|
||||||
import { ApMfmService } from './ApMfmService.js';
|
import { ApMfmService } from './ApMfmService.js';
|
||||||
import { CONTEXT } from './misc/contexts.js';
|
import { CONTEXT } from './misc/contexts.js';
|
||||||
import { getApId, IOrderedCollection, IOrderedCollectionPage } from './type.js';
|
import { getApId, ILink, IOrderedCollection, IOrderedCollectionPage } from './type.js';
|
||||||
import type { IAccept, IActivity, IAdd, IAnnounce, IApDocument, IApEmoji, IApHashtag, IApImage, IApMention, IBlock, ICreate, IDelete, IFlag, IFollow, IKey, ILike, IMove, IObject, IPost, IQuestion, IReject, IRemove, ITombstone, IUndo, IUpdate } from './type.js';
|
import type { IAccept, IActivity, IAdd, IAnnounce, IApDocument, IApEmoji, IApHashtag, IApImage, IApMention, IBlock, ICreate, IDelete, IFlag, IFollow, IKey, ILike, IMove, IObject, IPost, IQuestion, IReject, IRemove, ITombstone, IUndo, IUpdate } from './type.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -419,7 +419,7 @@ export class ApRendererService {
|
||||||
inReplyTo = null;
|
inReplyTo = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let quote;
|
let quote: string | undefined = undefined;
|
||||||
|
|
||||||
if (note.renoteId) {
|
if (note.renoteId) {
|
||||||
const renote = await this.notesRepository.findOneBy({ id: note.renoteId });
|
const renote = await this.notesRepository.findOneBy({ id: note.renoteId });
|
||||||
|
@ -500,12 +500,22 @@ export class ApRendererService {
|
||||||
const emojis = await this.getEmojis(note.emojis);
|
const emojis = await this.getEmojis(note.emojis);
|
||||||
const apemojis = emojis.filter(emoji => !emoji.localOnly).map(emoji => this.renderEmoji(emoji));
|
const apemojis = emojis.filter(emoji => !emoji.localOnly).map(emoji => this.renderEmoji(emoji));
|
||||||
|
|
||||||
const tag = [
|
const tag: IObject[] = [
|
||||||
...hashtagTags,
|
...hashtagTags,
|
||||||
...mentionTags,
|
...mentionTags,
|
||||||
...apemojis,
|
...apemojis,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// https://codeberg.org/fediverse/fep/src/branch/main/fep/e232/fep-e232.md
|
||||||
|
if (quote) {
|
||||||
|
tag.push({
|
||||||
|
type: 'Link',
|
||||||
|
mediaType: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||||
|
rel: 'https://misskey-hub.net/ns#_misskey_quote',
|
||||||
|
href: quote,
|
||||||
|
} satisfies ILink);
|
||||||
|
}
|
||||||
|
|
||||||
const asPoll = poll ? {
|
const asPoll = poll ? {
|
||||||
type: 'Question',
|
type: 'Question',
|
||||||
[poll.expiresAt && poll.expiresAt < new Date() ? 'closed' : 'endTime']: poll.expiresAt,
|
[poll.expiresAt && poll.expiresAt < new Date() ? 'closed' : 'endTime']: poll.expiresAt,
|
||||||
|
@ -537,6 +547,8 @@ export class ApRendererService {
|
||||||
_misskey_quote: quote,
|
_misskey_quote: quote,
|
||||||
quoteUrl: quote,
|
quoteUrl: quote,
|
||||||
quoteUri: quote,
|
quoteUri: quote,
|
||||||
|
// https://codeberg.org/fediverse/fep/src/branch/main/fep/044f/fep-044f.md
|
||||||
|
quote: quote,
|
||||||
published: this.idService.parse(note.id).date.toISOString(),
|
published: this.idService.parse(note.id).date.toISOString(),
|
||||||
to,
|
to,
|
||||||
cc,
|
cc,
|
||||||
|
@ -774,7 +786,7 @@ export class ApRendererService {
|
||||||
inReplyTo = null;
|
inReplyTo = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let quote;
|
let quote: string | undefined = undefined;
|
||||||
|
|
||||||
if (note.renoteId) {
|
if (note.renoteId) {
|
||||||
const renote = await this.notesRepository.findOneBy({ id: note.renoteId });
|
const renote = await this.notesRepository.findOneBy({ id: note.renoteId });
|
||||||
|
@ -852,12 +864,22 @@ export class ApRendererService {
|
||||||
const emojis = await this.getEmojis(note.emojis);
|
const emojis = await this.getEmojis(note.emojis);
|
||||||
const apemojis = emojis.filter(emoji => !emoji.localOnly).map(emoji => this.renderEmoji(emoji));
|
const apemojis = emojis.filter(emoji => !emoji.localOnly).map(emoji => this.renderEmoji(emoji));
|
||||||
|
|
||||||
const tag = [
|
const tag: IObject[] = [
|
||||||
...hashtagTags,
|
...hashtagTags,
|
||||||
...mentionTags,
|
...mentionTags,
|
||||||
...apemojis,
|
...apemojis,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// https://codeberg.org/fediverse/fep/src/branch/main/fep/e232/fep-e232.md
|
||||||
|
if (quote) {
|
||||||
|
tag.push({
|
||||||
|
type: 'Link',
|
||||||
|
mediaType: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||||
|
rel: 'https://misskey-hub.net/ns#_misskey_quote',
|
||||||
|
href: quote,
|
||||||
|
} satisfies ILink);
|
||||||
|
}
|
||||||
|
|
||||||
const asPoll = poll ? {
|
const asPoll = poll ? {
|
||||||
type: 'Question',
|
type: 'Question',
|
||||||
[poll.expiresAt && poll.expiresAt < new Date() ? 'closed' : 'endTime']: poll.expiresAt,
|
[poll.expiresAt && poll.expiresAt < new Date() ? 'closed' : 'endTime']: poll.expiresAt,
|
||||||
|
@ -886,6 +908,8 @@ export class ApRendererService {
|
||||||
_misskey_quote: quote,
|
_misskey_quote: quote,
|
||||||
quoteUrl: quote,
|
quoteUrl: quote,
|
||||||
quoteUri: quote,
|
quoteUri: quote,
|
||||||
|
// https://codeberg.org/fediverse/fep/src/branch/main/fep/044f/fep-044f.md
|
||||||
|
quote: quote,
|
||||||
published: this.idService.parse(note.id).date.toISOString(),
|
published: this.idService.parse(note.id).date.toISOString(),
|
||||||
to,
|
to,
|
||||||
cc,
|
cc,
|
||||||
|
|
|
@ -540,6 +540,10 @@ const extension_context_definition = {
|
||||||
quoteUrl: 'as:quoteUrl',
|
quoteUrl: 'as:quoteUrl',
|
||||||
fedibird: 'http://fedibird.com/ns#',
|
fedibird: 'http://fedibird.com/ns#',
|
||||||
quoteUri: 'fedibird:quoteUri',
|
quoteUri: 'fedibird:quoteUri',
|
||||||
|
quote: {
|
||||||
|
'@id': 'https://w3id.org/fep/044f#quote',
|
||||||
|
'@type': '@id',
|
||||||
|
},
|
||||||
// Mastodon
|
// Mastodon
|
||||||
toot: 'http://joinmastodon.org/ns#',
|
toot: 'http://joinmastodon.org/ns#',
|
||||||
Emoji: 'toot:Emoji',
|
Emoji: 'toot:Emoji',
|
||||||
|
|
|
@ -27,7 +27,7 @@ import { checkHttps } from '@/misc/check-https.js';
|
||||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||||
import { isRetryableError } from '@/misc/is-retryable-error.js';
|
import { isRetryableError } from '@/misc/is-retryable-error.js';
|
||||||
import { renderInlineError } from '@/misc/render-inline-error.js';
|
import { renderInlineError } from '@/misc/render-inline-error.js';
|
||||||
import { getOneApId, getApId, validPost, isEmoji, getApType, isApObject, isDocument, IApDocument } from '../type.js';
|
import { getOneApId, getApId, validPost, isEmoji, getApType, isApObject, isDocument, IApDocument, isLink } from '../type.js';
|
||||||
import { ApLoggerService } from '../ApLoggerService.js';
|
import { ApLoggerService } from '../ApLoggerService.js';
|
||||||
import { ApMfmService } from '../ApMfmService.js';
|
import { ApMfmService } from '../ApMfmService.js';
|
||||||
import { ApDbResolverService } from '../ApDbResolverService.js';
|
import { ApDbResolverService } from '../ApDbResolverService.js';
|
||||||
|
@ -657,9 +657,29 @@ export class ApNoteService {
|
||||||
*/
|
*/
|
||||||
private async getQuote(note: IPost, entryUri: string, resolver: Resolver): Promise<MiNote | null | undefined> {
|
private async getQuote(note: IPost, entryUri: string, resolver: Resolver): Promise<MiNote | null | undefined> {
|
||||||
const quoteUris = new Set<string>();
|
const quoteUris = new Set<string>();
|
||||||
if (note._misskey_quote) quoteUris.add(note._misskey_quote);
|
if (note._misskey_quote && typeof(note._misskey_quote as unknown) === 'string') quoteUris.add(note._misskey_quote);
|
||||||
if (note.quoteUrl) quoteUris.add(note.quoteUrl);
|
if (note.quoteUrl && typeof(note.quoteUrl as unknown) === 'string') quoteUris.add(note.quoteUrl);
|
||||||
if (note.quoteUri) quoteUris.add(note.quoteUri);
|
if (note.quoteUri && typeof(note.quoteUri as unknown) === 'string') quoteUris.add(note.quoteUri);
|
||||||
|
|
||||||
|
// https://codeberg.org/fediverse/fep/src/branch/main/fep/044f/fep-044f.md
|
||||||
|
if (note.quote && typeof(note.quote as unknown) === 'string') quoteUris.add(note.quote);
|
||||||
|
|
||||||
|
// https://codeberg.org/fediverse/fep/src/branch/main/fep/e232/fep-e232.md
|
||||||
|
const tags = toArray(note.tag).filter(tag => typeof(tag) === 'object' && isLink(tag));
|
||||||
|
for (const tag of tags) {
|
||||||
|
if (!tag.href || typeof (tag.href as unknown) !== 'string') continue;
|
||||||
|
|
||||||
|
const mediaTypes = toArray(tag.mediaType);
|
||||||
|
if (
|
||||||
|
!mediaTypes.includes('application/ld+json; profile="https://www.w3.org/ns/activitystreams"') &&
|
||||||
|
!mediaTypes.includes('application/activity+json')
|
||||||
|
) continue;
|
||||||
|
|
||||||
|
const rels = toArray(tag.rel);
|
||||||
|
if (!rels.includes('https://misskey-hub.net/ns#_misskey_quote')) continue;
|
||||||
|
|
||||||
|
quoteUris.add(tag.href);
|
||||||
|
}
|
||||||
|
|
||||||
// No quote, return undefined
|
// No quote, return undefined
|
||||||
if (quoteUris.size < 1) return undefined;
|
if (quoteUris.size < 1) return undefined;
|
||||||
|
|
|
@ -35,6 +35,7 @@ export interface IObject {
|
||||||
mediaType?: string;
|
mediaType?: string;
|
||||||
url?: ApObject | string;
|
url?: ApObject | string;
|
||||||
href?: string;
|
href?: string;
|
||||||
|
rel?: string | string[];
|
||||||
tag?: IObject | IObject[];
|
tag?: IObject | IObject[];
|
||||||
sensitive?: boolean;
|
sensitive?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -55,6 +56,16 @@ export function isAnonymousObject(object: IObject): object is IAnonymousObject {
|
||||||
return object.id === undefined;
|
return object.id === undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ILink extends IObject {
|
||||||
|
'@context'?: string | string[] | Obj | Obj[];
|
||||||
|
type: 'Link' | 'Mention';
|
||||||
|
href: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const isLink = (object: IObject): object is ILink =>
|
||||||
|
(getApType(object) === 'Link' || getApType(object) === 'Link') &&
|
||||||
|
typeof object.href === 'string';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get array of ActivityStreams Objects id
|
* Get array of ActivityStreams Objects id
|
||||||
*/
|
*/
|
||||||
|
@ -204,6 +215,7 @@ export interface IPost extends IObject {
|
||||||
_misskey_content?: string;
|
_misskey_content?: string;
|
||||||
quoteUrl?: string;
|
quoteUrl?: string;
|
||||||
quoteUri?: string;
|
quoteUri?: string;
|
||||||
|
quote?: string;
|
||||||
updated?: string;
|
updated?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,9 +318,8 @@ export const isPropertyValue = (object: IObject): object is IApPropertyValue =>
|
||||||
'value' in object &&
|
'value' in object &&
|
||||||
typeof object.value === 'string';
|
typeof object.value === 'string';
|
||||||
|
|
||||||
export interface IApMention extends IObject {
|
export interface IApMention extends ILink {
|
||||||
type: 'Mention';
|
type: 'Mention';
|
||||||
href: string;
|
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue