Skip to content

Commit

Permalink
Feature: block lists (#1531)
Browse files Browse the repository at this point in the history
* lexicons for block lists

* reorg blockset functionality into graph service, impl block/mute filtering

* apply filterBlocksAndMutes() throughout appview except feeds

* update local feeds to pass through cleanFeedSkeleton(), offload block/mute application

* impl for grabbing block/mute details by did pair

* refactor getActorInfos away, use actor service

* experiment with moving getFeedGenerators over to a pipeline

* move getPostThread over to a pipeline

* move feeds over to pipelines

* move suggestions and likes over to pipelines

* move reposted-by, follows, followers over to pipelines, tidy author feed and post thread

* remove old block/mute checks

* unify post presentation logic

* move profiles endpoints over to pipelines

* tidy

* tidy

* misc fixes

* unify some profile hydration/presentation in appview

* profile detail, split hydration and presentation, misc fixes

* unify feed hydration w/ profile hydration

* unify hydration step for embeds, tidy application of labels

* setup indexing of list-blocks in bsky appview

* apply list-blocks, impl getListBlocks, tidy getList, tests

* tidy

* update pds proxy snaps

* update pds proxy snaps

* fix snap

* make algos return feed items, save work in getFeed

* misc changes, tidy

* tidy

* fix aturi import

* hoist actors out of composeThread()

* tidy

* run ci on all prs

* format

* build

* proxy graph.getListBlocks

* remove unneeded index

* build pds

* setup noop listblock indexer on pds

* remove build

---------

Co-authored-by: dholms <[email protected]>
  • Loading branch information
devinivy and dholms authored Sep 12, 2023
1 parent fdf6a46 commit 6f41979
Show file tree
Hide file tree
Showing 82 changed files with 4,562 additions and 1,807 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/repo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Test
on:
pull_request:
branches:
- main
- '*'

concurrency:
group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}'
Expand Down
3 changes: 2 additions & 1 deletion lexicons/app/bsky/graph/defs.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@
"listViewerState": {
"type": "object",
"properties": {
"muted": { "type": "boolean" }
"muted": { "type": "boolean" },
"blocked": { "type": "string", "format": "at-uri" }
}
}
}
Expand Down
36 changes: 36 additions & 0 deletions lexicons/app/bsky/graph/getListBlocks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"lexicon": 1,
"id": "app.bsky.graph.getListBlocks",
"defs": {
"main": {
"type": "query",
"description": "Which lists is the requester's account blocking?",
"parameters": {
"type": "params",
"properties": {
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 50
},
"cursor": { "type": "string" }
}
},
"output": {
"encoding": "application/json",
"schema": {
"type": "object",
"required": ["lists"],
"properties": {
"cursor": { "type": "string" },
"lists": {
"type": "array",
"items": { "type": "ref", "ref": "app.bsky.graph.defs#listView" }
}
}
}
}
}
}
}
19 changes: 19 additions & 0 deletions lexicons/app/bsky/graph/listblock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"lexicon": 1,
"id": "app.bsky.graph.listblock",
"defs": {
"main": {
"type": "record",
"description": "A block of an entire list of actors.",
"key": "tid",
"record": {
"type": "object",
"required": ["subject", "createdAt"],
"properties": {
"subject": { "type": "string", "format": "at-uri" },
"createdAt": { "type": "string", "format": "datetime" }
}
}
}
}
}
82 changes: 82 additions & 0 deletions packages/api/src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,12 @@ import * as AppBskyGraphGetBlocks from './types/app/bsky/graph/getBlocks'
import * as AppBskyGraphGetFollowers from './types/app/bsky/graph/getFollowers'
import * as AppBskyGraphGetFollows from './types/app/bsky/graph/getFollows'
import * as AppBskyGraphGetList from './types/app/bsky/graph/getList'
import * as AppBskyGraphGetListBlocks from './types/app/bsky/graph/getListBlocks'
import * as AppBskyGraphGetListMutes from './types/app/bsky/graph/getListMutes'
import * as AppBskyGraphGetLists from './types/app/bsky/graph/getLists'
import * as AppBskyGraphGetMutes from './types/app/bsky/graph/getMutes'
import * as AppBskyGraphList from './types/app/bsky/graph/list'
import * as AppBskyGraphListblock from './types/app/bsky/graph/listblock'
import * as AppBskyGraphListitem from './types/app/bsky/graph/listitem'
import * as AppBskyGraphMuteActor from './types/app/bsky/graph/muteActor'
import * as AppBskyGraphMuteActorList from './types/app/bsky/graph/muteActorList'
Expand Down Expand Up @@ -232,10 +234,12 @@ export * as AppBskyGraphGetBlocks from './types/app/bsky/graph/getBlocks'
export * as AppBskyGraphGetFollowers from './types/app/bsky/graph/getFollowers'
export * as AppBskyGraphGetFollows from './types/app/bsky/graph/getFollows'
export * as AppBskyGraphGetList from './types/app/bsky/graph/getList'
export * as AppBskyGraphGetListBlocks from './types/app/bsky/graph/getListBlocks'
export * as AppBskyGraphGetListMutes from './types/app/bsky/graph/getListMutes'
export * as AppBskyGraphGetLists from './types/app/bsky/graph/getLists'
export * as AppBskyGraphGetMutes from './types/app/bsky/graph/getMutes'
export * as AppBskyGraphList from './types/app/bsky/graph/list'
export * as AppBskyGraphListblock from './types/app/bsky/graph/listblock'
export * as AppBskyGraphListitem from './types/app/bsky/graph/listitem'
export * as AppBskyGraphMuteActor from './types/app/bsky/graph/muteActor'
export * as AppBskyGraphMuteActorList from './types/app/bsky/graph/muteActorList'
Expand Down Expand Up @@ -1631,13 +1635,15 @@ export class GraphNS {
block: BlockRecord
follow: FollowRecord
list: ListRecord
listblock: ListblockRecord
listitem: ListitemRecord

constructor(service: AtpServiceClient) {
this._service = service
this.block = new BlockRecord(service)
this.follow = new FollowRecord(service)
this.list = new ListRecord(service)
this.listblock = new ListblockRecord(service)
this.listitem = new ListitemRecord(service)
}

Expand Down Expand Up @@ -1685,6 +1691,17 @@ export class GraphNS {
})
}

getListBlocks(
params?: AppBskyGraphGetListBlocks.QueryParams,
opts?: AppBskyGraphGetListBlocks.CallOptions,
): Promise<AppBskyGraphGetListBlocks.Response> {
return this._service.xrpc
.call('app.bsky.graph.getListBlocks', params, undefined, opts)
.catch((e) => {
throw AppBskyGraphGetListBlocks.toKnownErr(e)
})
}

getListMutes(
params?: AppBskyGraphGetListMutes.QueryParams,
opts?: AppBskyGraphGetListMutes.CallOptions,
Expand Down Expand Up @@ -1946,6 +1963,71 @@ export class ListRecord {
}
}

export class ListblockRecord {
_service: AtpServiceClient

constructor(service: AtpServiceClient) {
this._service = service
}

async list(
params: Omit<ComAtprotoRepoListRecords.QueryParams, 'collection'>,
): Promise<{
cursor?: string
records: { uri: string; value: AppBskyGraphListblock.Record }[]
}> {
const res = await this._service.xrpc.call('com.atproto.repo.listRecords', {
collection: 'app.bsky.graph.listblock',
...params,
})
return res.data
}

async get(
params: Omit<ComAtprotoRepoGetRecord.QueryParams, 'collection'>,
): Promise<{
uri: string
cid: string
value: AppBskyGraphListblock.Record
}> {
const res = await this._service.xrpc.call('com.atproto.repo.getRecord', {
collection: 'app.bsky.graph.listblock',
...params,
})
return res.data
}

async create(
params: Omit<
ComAtprotoRepoCreateRecord.InputSchema,
'collection' | 'record'
>,
record: AppBskyGraphListblock.Record,
headers?: Record<string, string>,
): Promise<{ uri: string; cid: string }> {
record.$type = 'app.bsky.graph.listblock'
const res = await this._service.xrpc.call(
'com.atproto.repo.createRecord',
undefined,
{ collection: 'app.bsky.graph.listblock', ...params, record },
{ encoding: 'application/json', headers },
)
return res.data
}

async delete(
params: Omit<ComAtprotoRepoDeleteRecord.InputSchema, 'collection'>,
headers?: Record<string, string>,
): Promise<void> {
await this._service.xrpc.call(
'com.atproto.repo.deleteRecord',
undefined,
{ collection: 'app.bsky.graph.listblock', ...params },
{ headers },
)
}
}

export class ListitemRecord {
_service: AtpServiceClient

Expand Down
74 changes: 74 additions & 0 deletions packages/api/src/client/lexicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5728,6 +5728,10 @@ export const schemaDict = {
muted: {
type: 'boolean',
},
blocked: {
type: 'string',
format: 'at-uri',
},
},
},
},
Expand Down Expand Up @@ -5956,6 +5960,49 @@ export const schemaDict = {
},
},
},
AppBskyGraphGetListBlocks: {
lexicon: 1,
id: 'app.bsky.graph.getListBlocks',
defs: {
main: {
type: 'query',
description: "Which lists is the requester's account blocking?",
parameters: {
type: 'params',
properties: {
limit: {
type: 'integer',
minimum: 1,
maximum: 100,
default: 50,
},
cursor: {
type: 'string',
},
},
},
output: {
encoding: 'application/json',
schema: {
type: 'object',
required: ['lists'],
properties: {
cursor: {
type: 'string',
},
lists: {
type: 'array',
items: {
type: 'ref',
ref: 'lex:app.bsky.graph.defs#listView',
},
},
},
},
},
},
},
},
AppBskyGraphGetListMutes: {
lexicon: 1,
id: 'app.bsky.graph.getListMutes',
Expand Down Expand Up @@ -6141,6 +6188,31 @@ export const schemaDict = {
},
},
},
AppBskyGraphListblock: {
lexicon: 1,
id: 'app.bsky.graph.listblock',
defs: {
main: {
type: 'record',
description: 'A block of an entire list of actors.',
key: 'tid',
record: {
type: 'object',
required: ['subject', 'createdAt'],
properties: {
subject: {
type: 'string',
format: 'at-uri',
},
createdAt: {
type: 'string',
format: 'datetime',
},
},
},
},
},
},
AppBskyGraphListitem: {
lexicon: 1,
id: 'app.bsky.graph.listitem',
Expand Down Expand Up @@ -6798,10 +6870,12 @@ export const ids = {
AppBskyGraphGetFollowers: 'app.bsky.graph.getFollowers',
AppBskyGraphGetFollows: 'app.bsky.graph.getFollows',
AppBskyGraphGetList: 'app.bsky.graph.getList',
AppBskyGraphGetListBlocks: 'app.bsky.graph.getListBlocks',
AppBskyGraphGetListMutes: 'app.bsky.graph.getListMutes',
AppBskyGraphGetLists: 'app.bsky.graph.getLists',
AppBskyGraphGetMutes: 'app.bsky.graph.getMutes',
AppBskyGraphList: 'app.bsky.graph.list',
AppBskyGraphListblock: 'app.bsky.graph.listblock',
AppBskyGraphListitem: 'app.bsky.graph.listitem',
AppBskyGraphMuteActor: 'app.bsky.graph.muteActor',
AppBskyGraphMuteActorList: 'app.bsky.graph.muteActorList',
Expand Down
1 change: 1 addition & 0 deletions packages/api/src/client/types/app/bsky/graph/defs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export const MODLIST = 'app.bsky.graph.defs#modlist'

export interface ListViewerState {
muted?: boolean
blocked?: string
[k: string]: unknown
}

Expand Down
38 changes: 38 additions & 0 deletions packages/api/src/client/types/app/bsky/graph/getListBlocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* GENERATED CODE - DO NOT MODIFY
*/
import { Headers, XRPCError } from '@atproto/xrpc'
import { ValidationResult, BlobRef } from '@atproto/lexicon'
import { isObj, hasProp } from '../../../../util'
import { lexicons } from '../../../../lexicons'
import { CID } from 'multiformats/cid'
import * as AppBskyGraphDefs from './defs'

export interface QueryParams {
limit?: number
cursor?: string
}

export type InputSchema = undefined

export interface OutputSchema {
cursor?: string
lists: AppBskyGraphDefs.ListView[]
[k: string]: unknown
}

export interface CallOptions {
headers?: Headers
}

export interface Response {
success: boolean
headers: Headers
data: OutputSchema
}

export function toKnownErr(e: any) {
if (e instanceof XRPCError) {
}
return e
}
26 changes: 26 additions & 0 deletions packages/api/src/client/types/app/bsky/graph/listblock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* GENERATED CODE - DO NOT MODIFY
*/
import { ValidationResult, BlobRef } from '@atproto/lexicon'
import { isObj, hasProp } from '../../../../util'
import { lexicons } from '../../../../lexicons'
import { CID } from 'multiformats/cid'

export interface Record {
subject: string
createdAt: string
[k: string]: unknown
}

export function isRecord(v: unknown): v is Record {
return (
isObj(v) &&
hasProp(v, '$type') &&
(v.$type === 'app.bsky.graph.listblock#main' ||
v.$type === 'app.bsky.graph.listblock')
)
}

export function validateRecord(v: unknown): ValidationResult {
return lexicons.validate('app.bsky.graph.listblock#main', v)
}
Loading

0 comments on commit 6f41979

Please sign in to comment.