Add ability to embed lists (#1188)
* add cid to ListView and ListViewBasic * add test for mute list embed * add support for list embeds views * test * port to appview * update missing snap --------- Co-authored-by: dholms <dtholmgren@gmail.com>
This commit is contained in:
parent
3da0324873
commit
0306f81d37
lexicons/app/bsky
packages
api/src/client
bsky
src
api/app/bsky/graph
lexicon
services
tests/views
pds
src
app-view
lexicon
tests
@ -20,7 +20,8 @@
|
||||
"#viewRecord",
|
||||
"#viewNotFound",
|
||||
"#viewBlocked",
|
||||
"app.bsky.feed.defs#generatorView"
|
||||
"app.bsky.feed.defs#generatorView",
|
||||
"app.bsky.graph.defs#listView"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,10 @@
|
||||
"defs": {
|
||||
"listViewBasic": {
|
||||
"type": "object",
|
||||
"required": ["uri", "name", "purpose"],
|
||||
"required": ["uri", "cid", "name", "purpose"],
|
||||
"properties": {
|
||||
"uri": {"type": "string", "format": "at-uri"},
|
||||
"cid": {"type": "string", "format": "cid"},
|
||||
"name": {"type": "string", "maxLength": 64, "minLength": 1},
|
||||
"purpose": {"type": "ref", "ref": "#listPurpose"},
|
||||
"avatar": {"type": "string"},
|
||||
@ -16,9 +17,10 @@
|
||||
},
|
||||
"listView": {
|
||||
"type": "object",
|
||||
"required": ["uri", "creator", "name", "purpose", "indexedAt"],
|
||||
"required": ["uri", "cid", "creator", "name", "purpose", "indexedAt"],
|
||||
"properties": {
|
||||
"uri": {"type": "string", "format": "at-uri"},
|
||||
"cid": {"type": "string", "format": "cid"},
|
||||
"creator": {"type": "ref", "ref": "app.bsky.actor.defs#profileView"},
|
||||
"name": {"type": "string", "maxLength": 64, "minLength": 1},
|
||||
"purpose": {"type": "ref", "ref": "#listPurpose"},
|
||||
|
@ -4136,6 +4136,7 @@ export const schemaDict = {
|
||||
'lex:app.bsky.embed.record#viewNotFound',
|
||||
'lex:app.bsky.embed.record#viewBlocked',
|
||||
'lex:app.bsky.feed.defs#generatorView',
|
||||
'lex:app.bsky.graph.defs#listView',
|
||||
],
|
||||
},
|
||||
},
|
||||
@ -5370,12 +5371,16 @@ export const schemaDict = {
|
||||
defs: {
|
||||
listViewBasic: {
|
||||
type: 'object',
|
||||
required: ['uri', 'name', 'purpose'],
|
||||
required: ['uri', 'cid', 'name', 'purpose'],
|
||||
properties: {
|
||||
uri: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
cid: {
|
||||
type: 'string',
|
||||
format: 'cid',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
maxLength: 64,
|
||||
@ -5400,12 +5405,16 @@ export const schemaDict = {
|
||||
},
|
||||
listView: {
|
||||
type: 'object',
|
||||
required: ['uri', 'creator', 'name', 'purpose', 'indexedAt'],
|
||||
required: ['uri', 'cid', 'creator', 'name', 'purpose', 'indexedAt'],
|
||||
properties: {
|
||||
uri: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
cid: {
|
||||
type: 'string',
|
||||
format: 'cid',
|
||||
},
|
||||
creator: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.actor.defs#profileView',
|
||||
|
@ -7,6 +7,7 @@ import { lexicons } from '../../../../lexicons'
|
||||
import { CID } from 'multiformats/cid'
|
||||
import * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef'
|
||||
import * as AppBskyFeedDefs from '../feed/defs'
|
||||
import * as AppBskyGraphDefs from '../graph/defs'
|
||||
import * as AppBskyActorDefs from '../actor/defs'
|
||||
import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs'
|
||||
import * as AppBskyEmbedImages from './images'
|
||||
@ -37,6 +38,7 @@ export interface View {
|
||||
| ViewNotFound
|
||||
| ViewBlocked
|
||||
| AppBskyFeedDefs.GeneratorView
|
||||
| AppBskyGraphDefs.ListView
|
||||
| { $type: string; [k: string]: unknown }
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import * as AppBskyRichtextFacet from '../richtext/facet'
|
||||
|
||||
export interface ListViewBasic {
|
||||
uri: string
|
||||
cid: string
|
||||
name: string
|
||||
purpose: ListPurpose
|
||||
avatar?: string
|
||||
@ -32,6 +33,7 @@ export function validateListViewBasic(v: unknown): ValidationResult {
|
||||
|
||||
export interface ListView {
|
||||
uri: string
|
||||
cid: string
|
||||
creator: AppBskyActorDefs.ProfileView
|
||||
name: string
|
||||
purpose: ListPurpose
|
||||
|
@ -57,6 +57,7 @@ export default function (server: Server, ctx: AppContext) {
|
||||
|
||||
const subject = {
|
||||
uri: listRes.uri,
|
||||
cid: listRes.cid,
|
||||
creator,
|
||||
name: listRes.name,
|
||||
purpose: listRes.purpose,
|
||||
|
@ -4136,6 +4136,7 @@ export const schemaDict = {
|
||||
'lex:app.bsky.embed.record#viewNotFound',
|
||||
'lex:app.bsky.embed.record#viewBlocked',
|
||||
'lex:app.bsky.feed.defs#generatorView',
|
||||
'lex:app.bsky.graph.defs#listView',
|
||||
],
|
||||
},
|
||||
},
|
||||
@ -5370,12 +5371,16 @@ export const schemaDict = {
|
||||
defs: {
|
||||
listViewBasic: {
|
||||
type: 'object',
|
||||
required: ['uri', 'name', 'purpose'],
|
||||
required: ['uri', 'cid', 'name', 'purpose'],
|
||||
properties: {
|
||||
uri: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
cid: {
|
||||
type: 'string',
|
||||
format: 'cid',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
maxLength: 64,
|
||||
@ -5400,12 +5405,16 @@ export const schemaDict = {
|
||||
},
|
||||
listView: {
|
||||
type: 'object',
|
||||
required: ['uri', 'creator', 'name', 'purpose', 'indexedAt'],
|
||||
required: ['uri', 'cid', 'creator', 'name', 'purpose', 'indexedAt'],
|
||||
properties: {
|
||||
uri: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
cid: {
|
||||
type: 'string',
|
||||
format: 'cid',
|
||||
},
|
||||
creator: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.actor.defs#profileView',
|
||||
|
@ -7,6 +7,7 @@ import { isObj, hasProp } from '../../../../util'
|
||||
import { CID } from 'multiformats/cid'
|
||||
import * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef'
|
||||
import * as AppBskyFeedDefs from '../feed/defs'
|
||||
import * as AppBskyGraphDefs from '../graph/defs'
|
||||
import * as AppBskyActorDefs from '../actor/defs'
|
||||
import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs'
|
||||
import * as AppBskyEmbedImages from './images'
|
||||
@ -37,6 +38,7 @@ export interface View {
|
||||
| ViewNotFound
|
||||
| ViewBlocked
|
||||
| AppBskyFeedDefs.GeneratorView
|
||||
| AppBskyGraphDefs.ListView
|
||||
| { $type: string; [k: string]: unknown }
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import * as AppBskyRichtextFacet from '../richtext/facet'
|
||||
|
||||
export interface ListViewBasic {
|
||||
uri: string
|
||||
cid: string
|
||||
name: string
|
||||
purpose: ListPurpose
|
||||
avatar?: string
|
||||
@ -32,6 +33,7 @@ export function validateListViewBasic(v: unknown): ValidationResult {
|
||||
|
||||
export interface ListView {
|
||||
uri: string
|
||||
cid: string
|
||||
creator: AppBskyActorDefs.ProfileView
|
||||
name: string
|
||||
purpose: ListPurpose
|
||||
|
@ -294,6 +294,7 @@ export class ActorViews {
|
||||
...acc,
|
||||
[cur.subjectDid]: {
|
||||
uri: cur.uri,
|
||||
cid: cur.cid,
|
||||
name: cur.name,
|
||||
purpose: cur.purpose,
|
||||
avatar: cur.avatarCid
|
||||
|
@ -23,6 +23,7 @@ import {
|
||||
} from '../types'
|
||||
import { LabelService } from '../label'
|
||||
import { ActorService } from '../actor'
|
||||
import { GraphService } from '../graph'
|
||||
import { FeedViews } from './views'
|
||||
import { FeedGenInfoMap } from './types'
|
||||
|
||||
@ -34,6 +35,7 @@ export class FeedService {
|
||||
services = {
|
||||
label: LabelService.creator()(this.db),
|
||||
actor: ActorService.creator(this.imgUriBuilder)(this.db),
|
||||
graph: GraphService.creator(this.imgUriBuilder)(this.db),
|
||||
}
|
||||
|
||||
static creator(imgUriBuilder: ImageUriBuilder) {
|
||||
@ -310,17 +312,24 @@ export class FeedService {
|
||||
const nestedFeedGenUris = nestedUris.filter(
|
||||
(uri) => new AtUri(uri).collection === ids.AppBskyFeedGenerator,
|
||||
)
|
||||
const [postViews, actorViews, deepEmbedViews, labelViews, feedGenViews] =
|
||||
await Promise.all([
|
||||
this.getPostViews(nestedPostUris, viewer),
|
||||
this.getActorViews(nestedDids, viewer, { skipLabels: true }),
|
||||
this.embedsForPosts(nestedUris, viewer, _depth + 1),
|
||||
this.services.label.getLabelsForSubjects([
|
||||
...nestedUris,
|
||||
...nestedDids,
|
||||
]),
|
||||
this.getFeedGeneratorViews(nestedFeedGenUris, viewer),
|
||||
])
|
||||
const nestedListUris = nestedUris.filter(
|
||||
(uri) => new AtUri(uri).collection === ids.AppBskyGraphList,
|
||||
)
|
||||
const [
|
||||
postViews,
|
||||
actorViews,
|
||||
deepEmbedViews,
|
||||
labelViews,
|
||||
feedGenViews,
|
||||
listViews,
|
||||
] = await Promise.all([
|
||||
this.getPostViews(nestedPostUris, viewer),
|
||||
this.getActorViews(nestedDids, viewer, { skipLabels: true }),
|
||||
this.embedsForPosts(nestedUris, viewer, _depth + 1),
|
||||
this.services.label.getLabelsForSubjects([...nestedUris, ...nestedDids]),
|
||||
this.getFeedGeneratorViews(nestedFeedGenUris, viewer),
|
||||
this.services.graph.getListViews(nestedListUris, viewer),
|
||||
])
|
||||
let embeds = images.reduce((acc, cur) => {
|
||||
const embed = (acc[cur.postUri] ??= {
|
||||
$type: 'app.bsky.embed.images#view',
|
||||
@ -378,6 +387,16 @@ export class FeedService {
|
||||
),
|
||||
},
|
||||
}
|
||||
} else if (collection === ids.AppBskyGraphList && listViews[cur.uri]) {
|
||||
recordEmbed = {
|
||||
record: {
|
||||
$type: 'app.bsky.graph.defs#listView',
|
||||
...this.services.graph.formatListView(
|
||||
listViews[cur.uri],
|
||||
actorViews,
|
||||
),
|
||||
},
|
||||
}
|
||||
} else if (collection === ids.AppBskyFeedPost && postViews[cur.uri]) {
|
||||
const formatted = this.views.formatPostView(
|
||||
cur.uri,
|
||||
|
@ -173,9 +173,24 @@ export class GraphService {
|
||||
}
|
||||
}
|
||||
|
||||
async getListViews(listUris: string[], requester: string | null) {
|
||||
if (listUris.length < 1) return {}
|
||||
const lists = await this.getListsQb(requester)
|
||||
.where('list.uri', 'in', listUris)
|
||||
.execute()
|
||||
return lists.reduce(
|
||||
(acc, cur) => ({
|
||||
...acc,
|
||||
[cur.uri]: cur,
|
||||
}),
|
||||
{},
|
||||
)
|
||||
}
|
||||
|
||||
formatListView(list: ListInfo, profiles: Record<string, ProfileView>) {
|
||||
return {
|
||||
uri: list.uri,
|
||||
cid: list.cid,
|
||||
creator: profiles[list.creator],
|
||||
name: list.name,
|
||||
purpose: list.purpose,
|
||||
|
@ -1,5 +1,66 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`bsky views with mutes from mute lists embeds lists in posts 1`] = `
|
||||
Object {
|
||||
"author": Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(1)@jpeg",
|
||||
"did": "user(0)",
|
||||
"displayName": "ali",
|
||||
"handle": "alice.test",
|
||||
"labels": Array [],
|
||||
"viewer": Object {
|
||||
"blockedBy": false,
|
||||
"muted": false,
|
||||
},
|
||||
},
|
||||
"cid": "cids(0)",
|
||||
"embed": Object {
|
||||
"$type": "app.bsky.embed.record#view",
|
||||
"record": Object {
|
||||
"$type": "app.bsky.graph.defs#listView",
|
||||
"cid": "cids(3)",
|
||||
"creator": Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(1)@jpeg",
|
||||
"did": "user(0)",
|
||||
"displayName": "ali",
|
||||
"handle": "alice.test",
|
||||
"viewer": Object {
|
||||
"blockedBy": false,
|
||||
"muted": false,
|
||||
},
|
||||
},
|
||||
"description": "new descript",
|
||||
"indexedAt": "1970-01-01T00:00:00.000Z",
|
||||
"name": "updated alice mutes",
|
||||
"purpose": "app.bsky.graph.defs#modlist",
|
||||
"uri": "record(1)",
|
||||
"viewer": Object {
|
||||
"muted": false,
|
||||
},
|
||||
},
|
||||
},
|
||||
"indexedAt": "1970-01-01T00:00:00.000Z",
|
||||
"labels": Array [],
|
||||
"likeCount": 0,
|
||||
"record": Object {
|
||||
"$type": "app.bsky.feed.post",
|
||||
"createdAt": "1970-01-01T00:00:00.000Z",
|
||||
"embed": Object {
|
||||
"$type": "app.bsky.embed.record",
|
||||
"record": Object {
|
||||
"cid": "cids(2)",
|
||||
"uri": "record(1)",
|
||||
},
|
||||
},
|
||||
"text": "list embed!",
|
||||
},
|
||||
"replyCount": 0,
|
||||
"repostCount": 0,
|
||||
"uri": "record(0)",
|
||||
"viewer": Object {},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`bsky views with mutes from mute lists flags mutes in threads 1`] = `
|
||||
Object {
|
||||
"$type": "app.bsky.feed.defs#threadViewPost",
|
||||
@ -48,6 +109,7 @@ Object {
|
||||
"muted": true,
|
||||
"mutedByList": Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(1)@jpeg",
|
||||
"cid": "cids(3)",
|
||||
"indexedAt": "1970-01-01T00:00:00.000Z",
|
||||
"name": "alice mutes",
|
||||
"purpose": "app.bsky.graph.defs#modlist",
|
||||
@ -98,6 +160,7 @@ Object {
|
||||
"muted": true,
|
||||
"mutedByList": Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(1)@jpeg",
|
||||
"cid": "cids(3)",
|
||||
"indexedAt": "1970-01-01T00:00:00.000Z",
|
||||
"name": "alice mutes",
|
||||
"purpose": "app.bsky.graph.defs#modlist",
|
||||
@ -108,21 +171,21 @@ Object {
|
||||
},
|
||||
},
|
||||
},
|
||||
"cid": "cids(3)",
|
||||
"cid": "cids(4)",
|
||||
"embed": Object {
|
||||
"$type": "app.bsky.embed.images#view",
|
||||
"images": Array [
|
||||
Object {
|
||||
"alt": "tests/image/fixtures/key-landscape-small.jpg",
|
||||
"fullsize": "https://bsky.public.url/image/sig()/rs:fit:2000:2000:1:0/plain/user(4)/cids(4)@jpeg",
|
||||
"thumb": "https://bsky.public.url/image/sig()/rs:fit:1000:1000:1:0/plain/user(4)/cids(4)@jpeg",
|
||||
"fullsize": "https://bsky.public.url/image/sig()/rs:fit:2000:2000:1:0/plain/user(4)/cids(5)@jpeg",
|
||||
"thumb": "https://bsky.public.url/image/sig()/rs:fit:1000:1000:1:0/plain/user(4)/cids(5)@jpeg",
|
||||
},
|
||||
],
|
||||
},
|
||||
"indexedAt": "1970-01-01T00:00:00.000Z",
|
||||
"labels": Array [
|
||||
Object {
|
||||
"cid": "cids(3)",
|
||||
"cid": "cids(4)",
|
||||
"cts": "1970-01-01T00:00:00.000Z",
|
||||
"neg": false,
|
||||
"src": "did:example:labeler",
|
||||
@ -130,7 +193,7 @@ Object {
|
||||
"val": "test-label",
|
||||
},
|
||||
Object {
|
||||
"cid": "cids(3)",
|
||||
"cid": "cids(4)",
|
||||
"cts": "1970-01-01T00:00:00.000Z",
|
||||
"neg": false,
|
||||
"src": "did:example:labeler",
|
||||
@ -151,7 +214,7 @@ Object {
|
||||
"$type": "blob",
|
||||
"mimeType": "image/jpeg",
|
||||
"ref": Object {
|
||||
"$link": "cids(4)",
|
||||
"$link": "cids(5)",
|
||||
},
|
||||
"size": 4114,
|
||||
},
|
||||
@ -185,8 +248,9 @@ Object {
|
||||
"cursor": "0000000000000::bafycid",
|
||||
"lists": Array [
|
||||
Object {
|
||||
"cid": "cids(0)",
|
||||
"creator": Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(0)@jpeg",
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(1)@jpeg",
|
||||
"description": "its me!",
|
||||
"did": "user(0)",
|
||||
"displayName": "ali",
|
||||
@ -209,9 +273,10 @@ Object {
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(0)@jpeg",
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(1)@jpeg",
|
||||
"cid": "cids(2)",
|
||||
"creator": Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(0)@jpeg",
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(1)@jpeg",
|
||||
"description": "its me!",
|
||||
"did": "user(0)",
|
||||
"displayName": "ali",
|
||||
@ -242,8 +307,9 @@ Object {
|
||||
"cursor": "0000000000000::bafycid",
|
||||
"lists": Array [
|
||||
Object {
|
||||
"cid": "cids(0)",
|
||||
"creator": Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(0)@jpeg",
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(1)@jpeg",
|
||||
"description": "its me!",
|
||||
"did": "user(0)",
|
||||
"displayName": "ali",
|
||||
@ -266,9 +332,10 @@ Object {
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(0)@jpeg",
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(1)@jpeg",
|
||||
"cid": "cids(2)",
|
||||
"creator": Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(0)@jpeg",
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(1)@jpeg",
|
||||
"description": "its me!",
|
||||
"did": "user(0)",
|
||||
"displayName": "ali",
|
||||
@ -308,7 +375,8 @@ Object {
|
||||
"followedBy": "record(1)",
|
||||
"muted": true,
|
||||
"mutedByList": Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(0)@jpeg",
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(1)@jpeg",
|
||||
"cid": "cids(0)",
|
||||
"indexedAt": "1970-01-01T00:00:00.000Z",
|
||||
"name": "alice mutes",
|
||||
"purpose": "app.bsky.graph.defs#modlist",
|
||||
@ -322,7 +390,7 @@ Object {
|
||||
},
|
||||
Object {
|
||||
"subject": Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(3)/cids(0)@jpeg",
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(3)/cids(1)@jpeg",
|
||||
"description": "hi im bob label_me",
|
||||
"did": "user(2)",
|
||||
"displayName": "bobby",
|
||||
@ -334,7 +402,8 @@ Object {
|
||||
"following": "record(2)",
|
||||
"muted": true,
|
||||
"mutedByList": Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(0)@jpeg",
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(1)@jpeg",
|
||||
"cid": "cids(0)",
|
||||
"indexedAt": "1970-01-01T00:00:00.000Z",
|
||||
"name": "alice mutes",
|
||||
"purpose": "app.bsky.graph.defs#modlist",
|
||||
@ -348,9 +417,10 @@ Object {
|
||||
},
|
||||
],
|
||||
"list": Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(0)@jpeg",
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(1)@jpeg",
|
||||
"cid": "cids(0)",
|
||||
"creator": Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(0)@jpeg",
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(1)@jpeg",
|
||||
"description": "its me!",
|
||||
"did": "user(4)",
|
||||
"displayName": "ali",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import AtpAgent, { AtUri } from '@atproto/api'
|
||||
import { TestNetwork } from '@atproto/dev-env'
|
||||
import { forSnapshot } from '../_util'
|
||||
import { SeedClient } from '../seeds/client'
|
||||
import { RecordRef, SeedClient } from '../seeds/client'
|
||||
import basicSeed from '../seeds/basic'
|
||||
|
||||
describe('bsky views with mutes from mute lists', () => {
|
||||
@ -38,6 +38,7 @@ describe('bsky views with mutes from mute lists', () => {
|
||||
})
|
||||
|
||||
let listUri: string
|
||||
let listCid: string
|
||||
|
||||
it('creates a list with some items', async () => {
|
||||
const avatar = await sc.uploadFile(
|
||||
@ -58,6 +59,7 @@ describe('bsky views with mutes from mute lists', () => {
|
||||
sc.getHeaders(alice),
|
||||
)
|
||||
listUri = list.uri
|
||||
listCid = list.cid
|
||||
await pdsAgent.api.app.bsky.graph.listitem.create(
|
||||
{ repo: alice },
|
||||
{
|
||||
@ -330,4 +332,21 @@ describe('bsky views with mutes from mute lists', () => {
|
||||
expect(got.data.list.avatar).toBeUndefined()
|
||||
expect(got.data.items.length).toBe(2)
|
||||
})
|
||||
|
||||
it('embeds lists in posts', async () => {
|
||||
const postRef = await sc.post(
|
||||
alice,
|
||||
'list embed!',
|
||||
undefined,
|
||||
undefined,
|
||||
new RecordRef(listUri, listCid),
|
||||
)
|
||||
await network.processAll()
|
||||
const res = await agent.api.app.bsky.feed.getPosts(
|
||||
{ uris: [postRef.ref.uriStr] },
|
||||
{ headers: await network.serviceHeaders(alice) },
|
||||
)
|
||||
expect(res.data.posts.length).toBe(1)
|
||||
expect(forSnapshot(res.data.posts[0])).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
|
@ -68,6 +68,7 @@ export default function (server: Server, ctx: AppContext) {
|
||||
|
||||
const subject = {
|
||||
uri: listRes.uri,
|
||||
cid: listRes.cid,
|
||||
creator,
|
||||
name: listRes.name,
|
||||
purpose: listRes.purpose,
|
||||
|
@ -265,6 +265,7 @@ export class ActorViews {
|
||||
...acc,
|
||||
[cur.subjectDid]: {
|
||||
uri: cur.uri,
|
||||
cid: cur.cid,
|
||||
name: cur.name,
|
||||
purpose: cur.purpose,
|
||||
avatar: cur.avatarCid
|
||||
|
@ -26,8 +26,9 @@ import {
|
||||
FeedGenInfoMap,
|
||||
} from './types'
|
||||
import { LabelService } from '../label'
|
||||
import { FeedViews } from './views'
|
||||
import { ActorService } from '../actor'
|
||||
import { GraphService } from '../graph'
|
||||
import { FeedViews } from './views'
|
||||
|
||||
export * from './types'
|
||||
|
||||
@ -42,6 +43,7 @@ export class FeedService {
|
||||
services = {
|
||||
label: LabelService.creator()(this.db),
|
||||
actor: ActorService.creator(this.imgUriBuilder)(this.db),
|
||||
graph: GraphService.creator(this.imgUriBuilder)(this.db),
|
||||
}
|
||||
|
||||
selectPostQb() {
|
||||
@ -297,17 +299,27 @@ export class FeedService {
|
||||
const nestedFeedGenUris = nestedUris.filter(
|
||||
(uri) => new AtUri(uri).collection === ids.AppBskyFeedGenerator,
|
||||
)
|
||||
const [postViews, actorViews, deepEmbedViews, labelViews, feedGenViews] =
|
||||
await Promise.all([
|
||||
this.getPostViews(nestedPostUris, requester),
|
||||
this.getActorViews(nestedDids, requester, { skipLabels: true }),
|
||||
this.embedsForPosts(nestedPostUris, requester, _depth + 1),
|
||||
this.services.label.getLabelsForSubjects([
|
||||
...nestedPostUris,
|
||||
...nestedDids,
|
||||
]),
|
||||
this.getFeedGeneratorViews(nestedFeedGenUris, requester),
|
||||
])
|
||||
const nestedListUris = nestedUris.filter(
|
||||
(uri) => new AtUri(uri).collection === ids.AppBskyGraphList,
|
||||
)
|
||||
const [
|
||||
postViews,
|
||||
actorViews,
|
||||
deepEmbedViews,
|
||||
labelViews,
|
||||
feedGenViews,
|
||||
listViews,
|
||||
] = await Promise.all([
|
||||
this.getPostViews(nestedPostUris, requester),
|
||||
this.getActorViews(nestedDids, requester, { skipLabels: true }),
|
||||
this.embedsForPosts(nestedPostUris, requester, _depth + 1),
|
||||
this.services.label.getLabelsForSubjects([
|
||||
...nestedPostUris,
|
||||
...nestedDids,
|
||||
]),
|
||||
this.getFeedGeneratorViews(nestedFeedGenUris, requester),
|
||||
this.services.graph.getListViews(nestedListUris, requester),
|
||||
])
|
||||
let embeds = images.reduce((acc, cur) => {
|
||||
const embed = (acc[cur.postUri] ??= {
|
||||
$type: 'app.bsky.embed.images#view',
|
||||
@ -360,6 +372,16 @@ export class FeedService {
|
||||
),
|
||||
},
|
||||
}
|
||||
} else if (collection === ids.AppBskyGraphList && listViews[cur.uri]) {
|
||||
recordEmbed = {
|
||||
record: {
|
||||
$type: 'app.bsky.graph.defs#listView',
|
||||
...this.services.graph.formatListView(
|
||||
listViews[cur.uri],
|
||||
actorViews,
|
||||
),
|
||||
},
|
||||
}
|
||||
} else if (collection === ids.AppBskyFeedPost && postViews[cur.uri]) {
|
||||
const formatted = this.views.formatPostView(
|
||||
cur.uri,
|
||||
|
@ -98,9 +98,24 @@ export class GraphService {
|
||||
}
|
||||
}
|
||||
|
||||
async getListViews(listUris: string[], requester: string) {
|
||||
if (listUris.length < 1) return {}
|
||||
const lists = await this.getListsQb(requester)
|
||||
.where('list.uri', 'in', listUris)
|
||||
.execute()
|
||||
return lists.reduce(
|
||||
(acc, cur) => ({
|
||||
...acc,
|
||||
[cur.uri]: cur,
|
||||
}),
|
||||
{},
|
||||
)
|
||||
}
|
||||
|
||||
formatListView(list: ListInfo, profiles: Record<string, ProfileView>) {
|
||||
return {
|
||||
uri: list.uri,
|
||||
cid: list.cid,
|
||||
creator: profiles[list.creator],
|
||||
name: list.name,
|
||||
purpose: list.purpose,
|
||||
|
@ -4136,6 +4136,7 @@ export const schemaDict = {
|
||||
'lex:app.bsky.embed.record#viewNotFound',
|
||||
'lex:app.bsky.embed.record#viewBlocked',
|
||||
'lex:app.bsky.feed.defs#generatorView',
|
||||
'lex:app.bsky.graph.defs#listView',
|
||||
],
|
||||
},
|
||||
},
|
||||
@ -5370,12 +5371,16 @@ export const schemaDict = {
|
||||
defs: {
|
||||
listViewBasic: {
|
||||
type: 'object',
|
||||
required: ['uri', 'name', 'purpose'],
|
||||
required: ['uri', 'cid', 'name', 'purpose'],
|
||||
properties: {
|
||||
uri: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
cid: {
|
||||
type: 'string',
|
||||
format: 'cid',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
maxLength: 64,
|
||||
@ -5400,12 +5405,16 @@ export const schemaDict = {
|
||||
},
|
||||
listView: {
|
||||
type: 'object',
|
||||
required: ['uri', 'creator', 'name', 'purpose', 'indexedAt'],
|
||||
required: ['uri', 'cid', 'creator', 'name', 'purpose', 'indexedAt'],
|
||||
properties: {
|
||||
uri: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
cid: {
|
||||
type: 'string',
|
||||
format: 'cid',
|
||||
},
|
||||
creator: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.actor.defs#profileView',
|
||||
|
@ -7,6 +7,7 @@ import { isObj, hasProp } from '../../../../util'
|
||||
import { CID } from 'multiformats/cid'
|
||||
import * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef'
|
||||
import * as AppBskyFeedDefs from '../feed/defs'
|
||||
import * as AppBskyGraphDefs from '../graph/defs'
|
||||
import * as AppBskyActorDefs from '../actor/defs'
|
||||
import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs'
|
||||
import * as AppBskyEmbedImages from './images'
|
||||
@ -37,6 +38,7 @@ export interface View {
|
||||
| ViewNotFound
|
||||
| ViewBlocked
|
||||
| AppBskyFeedDefs.GeneratorView
|
||||
| AppBskyGraphDefs.ListView
|
||||
| { $type: string; [k: string]: unknown }
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import * as AppBskyRichtextFacet from '../richtext/facet'
|
||||
|
||||
export interface ListViewBasic {
|
||||
uri: string
|
||||
cid: string
|
||||
name: string
|
||||
purpose: ListPurpose
|
||||
avatar?: string
|
||||
@ -32,6 +33,7 @@ export function validateListViewBasic(v: unknown): ValidationResult {
|
||||
|
||||
export interface ListView {
|
||||
uri: string
|
||||
cid: string
|
||||
creator: AppBskyActorDefs.ProfileView
|
||||
name: string
|
||||
purpose: ListPurpose
|
||||
|
@ -2030,6 +2030,7 @@ Object {
|
||||
},
|
||||
],
|
||||
"list": Object {
|
||||
"cid": "cids(1)",
|
||||
"creator": Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(4)/cids(0)@jpeg",
|
||||
"description": "hi im bob label_me",
|
||||
@ -2062,8 +2063,9 @@ Object {
|
||||
"cursor": "0000000000000::bafycid",
|
||||
"lists": Array [
|
||||
Object {
|
||||
"cid": "cids(0)",
|
||||
"creator": Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(0)@jpeg",
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(1)@jpeg",
|
||||
"description": "hi im bob label_me",
|
||||
"did": "user(0)",
|
||||
"displayName": "bobby",
|
||||
@ -2087,8 +2089,9 @@ Object {
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"cid": "cids(2)",
|
||||
"creator": Object {
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(0)@jpeg",
|
||||
"avatar": "https://bsky.public.url/image/sig()/rs:fill:1000:1000:1:0/plain/user(1)/cids(1)@jpeg",
|
||||
"description": "hi im bob label_me",
|
||||
"did": "user(0)",
|
||||
"displayName": "bobby",
|
||||
|
@ -1,5 +1,66 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`pds views with mutes from mute lists embeds lists in posts 1`] = `
|
||||
Object {
|
||||
"author": Object {
|
||||
"avatar": "https://pds.public.url/image/KzkHFsMRQ6oAKCHCRKFA1H-rDdc7VOtvEVpUJ82TwyQ/rs:fill:1000:1000:1:0/plain/bafkreiaivizp4xldojmmpuzmiu75cmea7nq56dnntnuhzhsjcb63aou5ei@jpeg",
|
||||
"did": "user(0)",
|
||||
"displayName": "ali",
|
||||
"handle": "alice.test",
|
||||
"labels": Array [],
|
||||
"viewer": Object {
|
||||
"blockedBy": false,
|
||||
"muted": false,
|
||||
},
|
||||
},
|
||||
"cid": "cids(0)",
|
||||
"embed": Object {
|
||||
"$type": "app.bsky.embed.record#view",
|
||||
"record": Object {
|
||||
"$type": "app.bsky.graph.defs#listView",
|
||||
"cid": "cids(2)",
|
||||
"creator": Object {
|
||||
"avatar": "https://pds.public.url/image/KzkHFsMRQ6oAKCHCRKFA1H-rDdc7VOtvEVpUJ82TwyQ/rs:fill:1000:1000:1:0/plain/bafkreiaivizp4xldojmmpuzmiu75cmea7nq56dnntnuhzhsjcb63aou5ei@jpeg",
|
||||
"did": "user(0)",
|
||||
"displayName": "ali",
|
||||
"handle": "alice.test",
|
||||
"viewer": Object {
|
||||
"blockedBy": false,
|
||||
"muted": false,
|
||||
},
|
||||
},
|
||||
"description": "new descript",
|
||||
"indexedAt": "1970-01-01T00:00:00.000Z",
|
||||
"name": "updated alice mutes",
|
||||
"purpose": "app.bsky.graph.defs#modlist",
|
||||
"uri": "record(1)",
|
||||
"viewer": Object {
|
||||
"muted": false,
|
||||
},
|
||||
},
|
||||
},
|
||||
"indexedAt": "1970-01-01T00:00:00.000Z",
|
||||
"labels": Array [],
|
||||
"likeCount": 0,
|
||||
"record": Object {
|
||||
"$type": "app.bsky.feed.post",
|
||||
"createdAt": "1970-01-01T00:00:00.000Z",
|
||||
"embed": Object {
|
||||
"$type": "app.bsky.embed.record",
|
||||
"record": Object {
|
||||
"cid": "cids(1)",
|
||||
"uri": "record(1)",
|
||||
},
|
||||
},
|
||||
"text": "list embed!",
|
||||
},
|
||||
"replyCount": 0,
|
||||
"repostCount": 0,
|
||||
"uri": "record(0)",
|
||||
"viewer": Object {},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`pds views with mutes from mute lists flags mutes in threads 1`] = `
|
||||
Object {
|
||||
"$type": "app.bsky.feed.defs#threadViewPost",
|
||||
@ -48,6 +109,7 @@ Object {
|
||||
"muted": true,
|
||||
"mutedByList": Object {
|
||||
"avatar": "https://pds.public.url/image/KzkHFsMRQ6oAKCHCRKFA1H-rDdc7VOtvEVpUJ82TwyQ/rs:fill:1000:1000:1:0/plain/bafkreiaivizp4xldojmmpuzmiu75cmea7nq56dnntnuhzhsjcb63aou5ei@jpeg",
|
||||
"cid": "cids(2)",
|
||||
"indexedAt": "1970-01-01T00:00:00.000Z",
|
||||
"name": "alice mutes",
|
||||
"purpose": "app.bsky.graph.defs#modlist",
|
||||
@ -98,6 +160,7 @@ Object {
|
||||
"muted": true,
|
||||
"mutedByList": Object {
|
||||
"avatar": "https://pds.public.url/image/KzkHFsMRQ6oAKCHCRKFA1H-rDdc7VOtvEVpUJ82TwyQ/rs:fill:1000:1000:1:0/plain/bafkreiaivizp4xldojmmpuzmiu75cmea7nq56dnntnuhzhsjcb63aou5ei@jpeg",
|
||||
"cid": "cids(2)",
|
||||
"indexedAt": "1970-01-01T00:00:00.000Z",
|
||||
"name": "alice mutes",
|
||||
"purpose": "app.bsky.graph.defs#modlist",
|
||||
@ -108,7 +171,7 @@ Object {
|
||||
},
|
||||
},
|
||||
},
|
||||
"cid": "cids(2)",
|
||||
"cid": "cids(3)",
|
||||
"embed": Object {
|
||||
"$type": "app.bsky.embed.images#view",
|
||||
"images": Array [
|
||||
@ -122,7 +185,7 @@ Object {
|
||||
"indexedAt": "1970-01-01T00:00:00.000Z",
|
||||
"labels": Array [
|
||||
Object {
|
||||
"cid": "cids(2)",
|
||||
"cid": "cids(3)",
|
||||
"cts": "1970-01-01T00:00:00.000Z",
|
||||
"neg": false,
|
||||
"src": "did:example:labeler",
|
||||
@ -130,7 +193,7 @@ Object {
|
||||
"val": "test-label",
|
||||
},
|
||||
Object {
|
||||
"cid": "cids(2)",
|
||||
"cid": "cids(3)",
|
||||
"cts": "1970-01-01T00:00:00.000Z",
|
||||
"neg": false,
|
||||
"src": "did:example:labeler",
|
||||
@ -151,7 +214,7 @@ Object {
|
||||
"$type": "blob",
|
||||
"mimeType": "image/jpeg",
|
||||
"ref": Object {
|
||||
"$link": "cids(3)",
|
||||
"$link": "cids(4)",
|
||||
},
|
||||
"size": 4114,
|
||||
},
|
||||
@ -185,6 +248,7 @@ Object {
|
||||
"cursor": "0000000000000::bafycid",
|
||||
"lists": Array [
|
||||
Object {
|
||||
"cid": "cids(0)",
|
||||
"creator": Object {
|
||||
"avatar": "https://pds.public.url/image/KzkHFsMRQ6oAKCHCRKFA1H-rDdc7VOtvEVpUJ82TwyQ/rs:fill:1000:1000:1:0/plain/bafkreiaivizp4xldojmmpuzmiu75cmea7nq56dnntnuhzhsjcb63aou5ei@jpeg",
|
||||
"description": "its me!",
|
||||
@ -210,6 +274,7 @@ Object {
|
||||
},
|
||||
Object {
|
||||
"avatar": "https://pds.public.url/image/KzkHFsMRQ6oAKCHCRKFA1H-rDdc7VOtvEVpUJ82TwyQ/rs:fill:1000:1000:1:0/plain/bafkreiaivizp4xldojmmpuzmiu75cmea7nq56dnntnuhzhsjcb63aou5ei@jpeg",
|
||||
"cid": "cids(1)",
|
||||
"creator": Object {
|
||||
"avatar": "https://pds.public.url/image/KzkHFsMRQ6oAKCHCRKFA1H-rDdc7VOtvEVpUJ82TwyQ/rs:fill:1000:1000:1:0/plain/bafkreiaivizp4xldojmmpuzmiu75cmea7nq56dnntnuhzhsjcb63aou5ei@jpeg",
|
||||
"description": "its me!",
|
||||
@ -242,6 +307,7 @@ Object {
|
||||
"cursor": "0000000000000::bafycid",
|
||||
"lists": Array [
|
||||
Object {
|
||||
"cid": "cids(0)",
|
||||
"creator": Object {
|
||||
"avatar": "https://pds.public.url/image/KzkHFsMRQ6oAKCHCRKFA1H-rDdc7VOtvEVpUJ82TwyQ/rs:fill:1000:1000:1:0/plain/bafkreiaivizp4xldojmmpuzmiu75cmea7nq56dnntnuhzhsjcb63aou5ei@jpeg",
|
||||
"description": "its me!",
|
||||
@ -267,6 +333,7 @@ Object {
|
||||
},
|
||||
Object {
|
||||
"avatar": "https://pds.public.url/image/KzkHFsMRQ6oAKCHCRKFA1H-rDdc7VOtvEVpUJ82TwyQ/rs:fill:1000:1000:1:0/plain/bafkreiaivizp4xldojmmpuzmiu75cmea7nq56dnntnuhzhsjcb63aou5ei@jpeg",
|
||||
"cid": "cids(1)",
|
||||
"creator": Object {
|
||||
"avatar": "https://pds.public.url/image/KzkHFsMRQ6oAKCHCRKFA1H-rDdc7VOtvEVpUJ82TwyQ/rs:fill:1000:1000:1:0/plain/bafkreiaivizp4xldojmmpuzmiu75cmea7nq56dnntnuhzhsjcb63aou5ei@jpeg",
|
||||
"description": "its me!",
|
||||
@ -309,6 +376,7 @@ Object {
|
||||
"muted": true,
|
||||
"mutedByList": Object {
|
||||
"avatar": "https://pds.public.url/image/KzkHFsMRQ6oAKCHCRKFA1H-rDdc7VOtvEVpUJ82TwyQ/rs:fill:1000:1000:1:0/plain/bafkreiaivizp4xldojmmpuzmiu75cmea7nq56dnntnuhzhsjcb63aou5ei@jpeg",
|
||||
"cid": "cids(0)",
|
||||
"indexedAt": "1970-01-01T00:00:00.000Z",
|
||||
"name": "alice mutes",
|
||||
"purpose": "app.bsky.graph.defs#modlist",
|
||||
@ -335,6 +403,7 @@ Object {
|
||||
"muted": true,
|
||||
"mutedByList": Object {
|
||||
"avatar": "https://pds.public.url/image/KzkHFsMRQ6oAKCHCRKFA1H-rDdc7VOtvEVpUJ82TwyQ/rs:fill:1000:1000:1:0/plain/bafkreiaivizp4xldojmmpuzmiu75cmea7nq56dnntnuhzhsjcb63aou5ei@jpeg",
|
||||
"cid": "cids(0)",
|
||||
"indexedAt": "1970-01-01T00:00:00.000Z",
|
||||
"name": "alice mutes",
|
||||
"purpose": "app.bsky.graph.defs#modlist",
|
||||
@ -349,6 +418,7 @@ Object {
|
||||
],
|
||||
"list": Object {
|
||||
"avatar": "https://pds.public.url/image/KzkHFsMRQ6oAKCHCRKFA1H-rDdc7VOtvEVpUJ82TwyQ/rs:fill:1000:1000:1:0/plain/bafkreiaivizp4xldojmmpuzmiu75cmea7nq56dnntnuhzhsjcb63aou5ei@jpeg",
|
||||
"cid": "cids(0)",
|
||||
"creator": Object {
|
||||
"avatar": "https://pds.public.url/image/KzkHFsMRQ6oAKCHCRKFA1H-rDdc7VOtvEVpUJ82TwyQ/rs:fill:1000:1000:1:0/plain/bafkreiaivizp4xldojmmpuzmiu75cmea7nq56dnntnuhzhsjcb63aou5ei@jpeg",
|
||||
"description": "its me!",
|
||||
|
@ -2,6 +2,7 @@ import AtpAgent, { AtUri } from '@atproto/api'
|
||||
import { runTestServer, CloseFn, TestServerInfo, forSnapshot } from '../_util'
|
||||
import { SeedClient } from '../seeds/client'
|
||||
import basicSeed from '../seeds/basic'
|
||||
import { RecordRef } from '../seeds/client'
|
||||
|
||||
describe('pds views with mutes from mute lists', () => {
|
||||
let server: TestServerInfo
|
||||
@ -37,6 +38,7 @@ describe('pds views with mutes from mute lists', () => {
|
||||
})
|
||||
|
||||
let listUri: string
|
||||
let listCid: string
|
||||
|
||||
it('creates a list with some items', async () => {
|
||||
const avatar = await sc.uploadFile(
|
||||
@ -57,6 +59,7 @@ describe('pds views with mutes from mute lists', () => {
|
||||
sc.getHeaders(alice),
|
||||
)
|
||||
listUri = list.uri
|
||||
listCid = list.cid
|
||||
await agent.api.app.bsky.graph.listitem.create(
|
||||
{ repo: alice },
|
||||
{
|
||||
@ -333,4 +336,20 @@ describe('pds views with mutes from mute lists', () => {
|
||||
expect(got.data.list.avatar).toBeUndefined()
|
||||
expect(got.data.items.length).toBe(2)
|
||||
})
|
||||
|
||||
it('embeds lists in posts', async () => {
|
||||
const postRef = await sc.post(
|
||||
alice,
|
||||
'list embed!',
|
||||
undefined,
|
||||
undefined,
|
||||
new RecordRef(listUri, listCid),
|
||||
)
|
||||
const res = await agent.api.app.bsky.feed.getPosts(
|
||||
{ uris: [postRef.ref.uriStr] },
|
||||
{ headers: sc.getHeaders(alice) },
|
||||
)
|
||||
expect(res.data.posts.length).toBe(1)
|
||||
expect(forSnapshot(res.data.posts[0])).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user