diff --git a/README.md b/README.md index 34dcee4..91e8901 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,21 @@ Readers write these in their own repos. - **`graph.subscription`**: follows a series. Delete it to unsubscribe. - **`graph.list`**: a reading list or reading order of chapters and strips from any creator. AppViews skip items that aren't chapters or strips, or that were deleted. +- **`feed.like`**: likes a chapter or strip. Delete it to unlike. +- **`feed.comment`**: comments on a chapter or strip. Replies set `parent` to the comment they reply to and keep its `subject`, so AppViews can count a work's comments without walking threads. + +A reply to a comment on a chapter: + +```json +{ + "$type": "work.sequential.feed.comment", + "subject": "at://did:plc:creator/work.sequential.chapter/3kchapter", + "parent": "at://did:plc:reader/work.sequential.feed.comment/3kcomment", + "text": "That last page got me too.", + "lang": "en", + "createdAt": "2026-10-03T12:00:00.000Z" +} +``` ### Publishing @@ -227,6 +242,24 @@ Different art (Cover B) is its own record. The same art with a different treatme | `series` | at-uri | yes | | `createdAt` | datetime | yes | +### `work.sequential.feed.like` + +| Property | Type | Req | Notes | +| --- | --- | --- | --- | +| `subject` | at-uri | yes | Chapter or strip. | +| `createdAt` | datetime | yes | | + +### `work.sequential.feed.comment` + +| Property | Type | Req | Notes | +| --- | --- | --- | --- | +| `subject` | at-uri | yes | Chapter or strip. Replies keep their parent's. | +| `parent` | at-uri | no | Comment being replied to. | +| `text` | string (≤ 1000 graphemes) | yes | | +| `facets` | `app.bsky.richtext.facet[]` | no | Mentions, links, hashtags. | +| `lang` | language | no | | +| `createdAt` | datetime | yes | | + ### `work.sequential.defs` **`panel`**: all fields optional. See [Panels](#panels). diff --git a/src/lexicons/work.sequential.feed.comment.ts b/src/lexicons/work.sequential.feed.comment.ts new file mode 100644 index 0000000..31ee185 --- /dev/null +++ b/src/lexicons/work.sequential.feed.comment.ts @@ -0,0 +1,37 @@ +import { lx } from 'prototypey' + +export const workSequentialFeedComment = lx.lexicon('work.sequential.feed.comment', { + main: lx.record({ + key: 'tid', + record: lx.object({ + subject: lx.string({ + format: 'at-uri', + required: true, + description: 'AT-URI of the work.sequential.chapter or work.sequential.strip being commented on. AppViews ignore comments on any other record. Replies keep the subject of the comment they reply to. Use the DID form (at://did:...), not a handle.' + }), + parent: lx.string({ + format: 'at-uri', + description: 'AT-URI of the work.sequential.feed.comment being replied to. Omit for a top-level comment. Use the DID form (at://did:...), not a handle.' + }), + text: lx.string({ + maxLength: 10000, + maxGraphemes: 1000, + required: true, + description: 'The comment text.' + }), + facets: lx.array(lx.ref('app.bsky.richtext.facet'), { + description: 'Annotations of text (mentions, URLs, hashtags, etc).' + }), + lang: lx.string({ + format: 'language', + description: 'BCP-47 language tag for the text.' + }), + createdAt: lx.string({ + format: 'datetime', + required: true, + description: 'The date and time the comment was created.' + }) + }), + description: 'A comment on a chapter or strip, or a reply to another comment.' + }) +}) diff --git a/src/lexicons/work.sequential.feed.like.ts b/src/lexicons/work.sequential.feed.like.ts new file mode 100644 index 0000000..75b608d --- /dev/null +++ b/src/lexicons/work.sequential.feed.like.ts @@ -0,0 +1,20 @@ +import { lx } from 'prototypey' + +export const workSequentialFeedLike = lx.lexicon('work.sequential.feed.like', { + main: lx.record({ + key: 'tid', + record: lx.object({ + subject: lx.string({ + format: 'at-uri', + required: true, + description: 'AT-URI of the work.sequential.chapter or work.sequential.strip being liked. AppViews ignore likes of any other record. Use the DID form (at://did:...), not a handle.' + }), + createdAt: lx.string({ + format: 'datetime', + required: true, + description: 'The date and time the like was created.' + }) + }), + description: 'Record declaring a like of a chapter or strip. Delete it to unlike.' + }) +})