@atproto/bsky 0.0.154 → 0.0.156
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/api/app/bsky/unspecced/{getPostThreadHiddenV2.d.ts → getPostThreadOtherV2.d.ts} +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.d.ts.map +1 -0
- package/dist/api/app/bsky/unspecced/{getPostThreadHiddenV2.js → getPostThreadOtherV2.js} +5 -5
- package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.js.map +1 -0
- package/dist/api/app/bsky/unspecced/getPostThreadV2.js +2 -2
- package/dist/api/app/bsky/unspecced/getPostThreadV2.js.map +1 -1
- package/dist/api/index.js +2 -2
- package/dist/api/index.js.map +1 -1
- package/dist/lexicon/index.d.ts +4 -4
- package/dist/lexicon/index.d.ts.map +1 -1
- package/dist/lexicon/index.js +6 -6
- package/dist/lexicon/index.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +100 -100
- package/dist/lexicon/lexicons.js +52 -52
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/{getPostThreadHiddenV2.d.ts → getPostThreadOtherV2.d.ts} +7 -7
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadOtherV2.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadOtherV2.js +16 -0
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadOtherV2.js.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadV2.d.ts +2 -2
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadV2.d.ts.map +1 -1
- package/dist/views/index.d.ts +8 -8
- package/dist/views/index.d.ts.map +1 -1
- package/dist/views/index.js +32 -32
- package/dist/views/index.js.map +1 -1
- package/dist/views/threads-v2.d.ts +11 -11
- package/dist/views/threads-v2.d.ts.map +1 -1
- package/dist/views/threads-v2.js.map +1 -1
- package/package.json +11 -11
- package/src/api/app/bsky/unspecced/{getPostThreadHiddenV2.ts → getPostThreadOtherV2.ts} +5 -5
- package/src/api/app/bsky/unspecced/getPostThreadV2.ts +2 -2
- package/src/api/index.ts +2 -2
- package/src/lexicon/index.ts +14 -14
- package/src/lexicon/lexicons.ts +54 -54
- package/src/lexicon/types/app/bsky/unspecced/{getPostThreadHiddenV2.ts → getPostThreadOtherV2.ts} +10 -10
- package/src/lexicon/types/app/bsky/unspecced/getPostThreadV2.ts +2 -2
- package/src/views/index.ts +46 -46
- package/src/views/threads-v2.ts +23 -23
- package/tests/views/__snapshots__/thread-v2.test.ts.snap +7 -7
- package/tests/views/thread-v2.test.ts +93 -93
- package/tsconfig.build.tsbuildinfo +1 -1
- package/tsconfig.tests.tsbuildinfo +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadHiddenV2.d.ts.map +0 -1
- package/dist/api/app/bsky/unspecced/getPostThreadHiddenV2.js.map +0 -1
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadHiddenV2.d.ts.map +0 -1
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadHiddenV2.js +0 -16
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadHiddenV2.js.map +0 -1
package/src/lexicon/lexicons.ts
CHANGED
|
@@ -7239,6 +7239,48 @@ export const schemaDict = {
|
|
|
7239
7239
|
},
|
|
7240
7240
|
},
|
|
7241
7241
|
},
|
|
7242
|
+
AppBskyFeedGetPosts: {
|
|
7243
|
+
lexicon: 1,
|
|
7244
|
+
id: 'app.bsky.feed.getPosts',
|
|
7245
|
+
defs: {
|
|
7246
|
+
main: {
|
|
7247
|
+
type: 'query',
|
|
7248
|
+
description:
|
|
7249
|
+
"Gets post views for a specified list of posts (by AT-URI). This is sometimes referred to as 'hydrating' a 'feed skeleton'.",
|
|
7250
|
+
parameters: {
|
|
7251
|
+
type: 'params',
|
|
7252
|
+
required: ['uris'],
|
|
7253
|
+
properties: {
|
|
7254
|
+
uris: {
|
|
7255
|
+
type: 'array',
|
|
7256
|
+
description: 'List of post AT-URIs to return hydrated views for.',
|
|
7257
|
+
items: {
|
|
7258
|
+
type: 'string',
|
|
7259
|
+
format: 'at-uri',
|
|
7260
|
+
},
|
|
7261
|
+
maxLength: 25,
|
|
7262
|
+
},
|
|
7263
|
+
},
|
|
7264
|
+
},
|
|
7265
|
+
output: {
|
|
7266
|
+
encoding: 'application/json',
|
|
7267
|
+
schema: {
|
|
7268
|
+
type: 'object',
|
|
7269
|
+
required: ['posts'],
|
|
7270
|
+
properties: {
|
|
7271
|
+
posts: {
|
|
7272
|
+
type: 'array',
|
|
7273
|
+
items: {
|
|
7274
|
+
type: 'ref',
|
|
7275
|
+
ref: 'lex:app.bsky.feed.defs#postView',
|
|
7276
|
+
},
|
|
7277
|
+
},
|
|
7278
|
+
},
|
|
7279
|
+
},
|
|
7280
|
+
},
|
|
7281
|
+
},
|
|
7282
|
+
},
|
|
7283
|
+
},
|
|
7242
7284
|
AppBskyFeedGetPostThread: {
|
|
7243
7285
|
lexicon: 1,
|
|
7244
7286
|
id: 'app.bsky.feed.getPostThread',
|
|
@@ -7303,48 +7345,6 @@ export const schemaDict = {
|
|
|
7303
7345
|
},
|
|
7304
7346
|
},
|
|
7305
7347
|
},
|
|
7306
|
-
AppBskyFeedGetPosts: {
|
|
7307
|
-
lexicon: 1,
|
|
7308
|
-
id: 'app.bsky.feed.getPosts',
|
|
7309
|
-
defs: {
|
|
7310
|
-
main: {
|
|
7311
|
-
type: 'query',
|
|
7312
|
-
description:
|
|
7313
|
-
"Gets post views for a specified list of posts (by AT-URI). This is sometimes referred to as 'hydrating' a 'feed skeleton'.",
|
|
7314
|
-
parameters: {
|
|
7315
|
-
type: 'params',
|
|
7316
|
-
required: ['uris'],
|
|
7317
|
-
properties: {
|
|
7318
|
-
uris: {
|
|
7319
|
-
type: 'array',
|
|
7320
|
-
description: 'List of post AT-URIs to return hydrated views for.',
|
|
7321
|
-
items: {
|
|
7322
|
-
type: 'string',
|
|
7323
|
-
format: 'at-uri',
|
|
7324
|
-
},
|
|
7325
|
-
maxLength: 25,
|
|
7326
|
-
},
|
|
7327
|
-
},
|
|
7328
|
-
},
|
|
7329
|
-
output: {
|
|
7330
|
-
encoding: 'application/json',
|
|
7331
|
-
schema: {
|
|
7332
|
-
type: 'object',
|
|
7333
|
-
required: ['posts'],
|
|
7334
|
-
properties: {
|
|
7335
|
-
posts: {
|
|
7336
|
-
type: 'array',
|
|
7337
|
-
items: {
|
|
7338
|
-
type: 'ref',
|
|
7339
|
-
ref: 'lex:app.bsky.feed.defs#postView',
|
|
7340
|
-
},
|
|
7341
|
-
},
|
|
7342
|
-
},
|
|
7343
|
-
},
|
|
7344
|
-
},
|
|
7345
|
-
},
|
|
7346
|
-
},
|
|
7347
|
-
},
|
|
7348
7348
|
AppBskyFeedGetQuotes: {
|
|
7349
7349
|
lexicon: 1,
|
|
7350
7350
|
id: 'app.bsky.feed.getQuotes',
|
|
@@ -10354,14 +10354,14 @@ export const schemaDict = {
|
|
|
10354
10354
|
},
|
|
10355
10355
|
},
|
|
10356
10356
|
},
|
|
10357
|
-
|
|
10357
|
+
AppBskyUnspeccedGetPostThreadOtherV2: {
|
|
10358
10358
|
lexicon: 1,
|
|
10359
|
-
id: 'app.bsky.unspecced.
|
|
10359
|
+
id: 'app.bsky.unspecced.getPostThreadOtherV2',
|
|
10360
10360
|
defs: {
|
|
10361
10361
|
main: {
|
|
10362
10362
|
type: 'query',
|
|
10363
10363
|
description:
|
|
10364
|
-
"(NOTE: this endpoint is under development and WILL change without notice. Don't use it until it is moved out of `unspecced` or your application WILL break) Get
|
|
10364
|
+
"(NOTE: this endpoint is under development and WILL change without notice. Don't use it until it is moved out of `unspecced` or your application WILL break) Get additional posts under a thread e.g. replies hidden by threadgate. Based on an anchor post at any depth of the tree, returns top-level replies below that anchor. It does not include ancestors nor the anchor itself. This should be called after exhausting `app.bsky.unspecced.getPostThreadV2`. Does not require auth, but additional metadata and filtering will be applied for authed requests.",
|
|
10365
10365
|
parameters: {
|
|
10366
10366
|
type: 'params',
|
|
10367
10367
|
required: ['anchor'],
|
|
@@ -10389,17 +10389,17 @@ export const schemaDict = {
|
|
|
10389
10389
|
thread: {
|
|
10390
10390
|
type: 'array',
|
|
10391
10391
|
description:
|
|
10392
|
-
'A flat list of
|
|
10392
|
+
'A flat list of other thread items. The depth of each item is indicated by the depth property inside the item.',
|
|
10393
10393
|
items: {
|
|
10394
10394
|
type: 'ref',
|
|
10395
|
-
ref: 'lex:app.bsky.unspecced.
|
|
10395
|
+
ref: 'lex:app.bsky.unspecced.getPostThreadOtherV2#threadItem',
|
|
10396
10396
|
},
|
|
10397
10397
|
},
|
|
10398
10398
|
},
|
|
10399
10399
|
},
|
|
10400
10400
|
},
|
|
10401
10401
|
},
|
|
10402
|
-
|
|
10402
|
+
threadItem: {
|
|
10403
10403
|
type: 'object',
|
|
10404
10404
|
required: ['uri', 'depth', 'value'],
|
|
10405
10405
|
properties: {
|
|
@@ -10477,7 +10477,7 @@ export const schemaDict = {
|
|
|
10477
10477
|
encoding: 'application/json',
|
|
10478
10478
|
schema: {
|
|
10479
10479
|
type: 'object',
|
|
10480
|
-
required: ['thread', '
|
|
10480
|
+
required: ['thread', 'hasOtherReplies'],
|
|
10481
10481
|
properties: {
|
|
10482
10482
|
thread: {
|
|
10483
10483
|
type: 'array',
|
|
@@ -10492,10 +10492,10 @@ export const schemaDict = {
|
|
|
10492
10492
|
type: 'ref',
|
|
10493
10493
|
ref: 'lex:app.bsky.feed.defs#threadgateView',
|
|
10494
10494
|
},
|
|
10495
|
-
|
|
10495
|
+
hasOtherReplies: {
|
|
10496
10496
|
type: 'boolean',
|
|
10497
10497
|
description:
|
|
10498
|
-
'Whether this thread has
|
|
10498
|
+
'Whether this thread has additional replies. If true, a call can be made to the `getPostThreadOtherV2` endpoint to retrieve them.',
|
|
10499
10499
|
},
|
|
10500
10500
|
},
|
|
10501
10501
|
},
|
|
@@ -12892,8 +12892,8 @@ export const ids = {
|
|
|
12892
12892
|
AppBskyFeedGetFeedSkeleton: 'app.bsky.feed.getFeedSkeleton',
|
|
12893
12893
|
AppBskyFeedGetLikes: 'app.bsky.feed.getLikes',
|
|
12894
12894
|
AppBskyFeedGetListFeed: 'app.bsky.feed.getListFeed',
|
|
12895
|
-
AppBskyFeedGetPostThread: 'app.bsky.feed.getPostThread',
|
|
12896
12895
|
AppBskyFeedGetPosts: 'app.bsky.feed.getPosts',
|
|
12896
|
+
AppBskyFeedGetPostThread: 'app.bsky.feed.getPostThread',
|
|
12897
12897
|
AppBskyFeedGetQuotes: 'app.bsky.feed.getQuotes',
|
|
12898
12898
|
AppBskyFeedGetRepostedBy: 'app.bsky.feed.getRepostedBy',
|
|
12899
12899
|
AppBskyFeedGetSuggestedFeeds: 'app.bsky.feed.getSuggestedFeeds',
|
|
@@ -12950,8 +12950,8 @@ export const ids = {
|
|
|
12950
12950
|
AppBskyUnspeccedGetConfig: 'app.bsky.unspecced.getConfig',
|
|
12951
12951
|
AppBskyUnspeccedGetPopularFeedGenerators:
|
|
12952
12952
|
'app.bsky.unspecced.getPopularFeedGenerators',
|
|
12953
|
-
|
|
12954
|
-
'app.bsky.unspecced.
|
|
12953
|
+
AppBskyUnspeccedGetPostThreadOtherV2:
|
|
12954
|
+
'app.bsky.unspecced.getPostThreadOtherV2',
|
|
12955
12955
|
AppBskyUnspeccedGetPostThreadV2: 'app.bsky.unspecced.getPostThreadV2',
|
|
12956
12956
|
AppBskyUnspeccedGetSuggestedFeeds: 'app.bsky.unspecced.getSuggestedFeeds',
|
|
12957
12957
|
AppBskyUnspeccedGetSuggestedFeedsSkeleton:
|
package/src/lexicon/types/app/bsky/unspecced/{getPostThreadHiddenV2.ts → getPostThreadOtherV2.ts}
RENAMED
|
@@ -15,7 +15,7 @@ import type * as AppBskyUnspeccedDefs from './defs.js'
|
|
|
15
15
|
|
|
16
16
|
const is$typed = _is$typed,
|
|
17
17
|
validate = _validate
|
|
18
|
-
const id = 'app.bsky.unspecced.
|
|
18
|
+
const id = 'app.bsky.unspecced.getPostThreadOtherV2'
|
|
19
19
|
|
|
20
20
|
export interface QueryParams {
|
|
21
21
|
/** Reference (AT-URI) to post record. This is the anchor post. */
|
|
@@ -27,8 +27,8 @@ export interface QueryParams {
|
|
|
27
27
|
export type InputSchema = undefined
|
|
28
28
|
|
|
29
29
|
export interface OutputSchema {
|
|
30
|
-
/** A flat list of
|
|
31
|
-
thread:
|
|
30
|
+
/** A flat list of other thread items. The depth of each item is indicated by the depth property inside the item. */
|
|
31
|
+
thread: ThreadItem[]
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export type HandlerInput = undefined
|
|
@@ -57,20 +57,20 @@ export type Handler<HA extends HandlerAuth = never> = (
|
|
|
57
57
|
ctx: HandlerReqCtx<HA>,
|
|
58
58
|
) => Promise<HandlerOutput> | HandlerOutput
|
|
59
59
|
|
|
60
|
-
export interface
|
|
61
|
-
$type?: 'app.bsky.unspecced.
|
|
60
|
+
export interface ThreadItem {
|
|
61
|
+
$type?: 'app.bsky.unspecced.getPostThreadOtherV2#threadItem'
|
|
62
62
|
uri: string
|
|
63
63
|
/** The nesting level of this item in the thread. Depth 0 means the anchor item. Items above have negative depths, items below have positive depths. */
|
|
64
64
|
depth: number
|
|
65
65
|
value: $Typed<AppBskyUnspeccedDefs.ThreadItemPost> | { $type: string }
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
const
|
|
68
|
+
const hashThreadItem = 'threadItem'
|
|
69
69
|
|
|
70
|
-
export function
|
|
71
|
-
return is$typed(v, id,
|
|
70
|
+
export function isThreadItem<V>(v: V) {
|
|
71
|
+
return is$typed(v, id, hashThreadItem)
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
export function
|
|
75
|
-
return validate<
|
|
74
|
+
export function validateThreadItem<V>(v: V) {
|
|
75
|
+
return validate<ThreadItem & V>(v, id, hashThreadItem)
|
|
76
76
|
}
|
|
@@ -39,8 +39,8 @@ export interface OutputSchema {
|
|
|
39
39
|
/** A flat list of thread items. The depth of each item is indicated by the depth property inside the item. */
|
|
40
40
|
thread: ThreadItem[]
|
|
41
41
|
threadgate?: AppBskyFeedDefs.ThreadgateView
|
|
42
|
-
/** Whether this thread has
|
|
43
|
-
|
|
42
|
+
/** Whether this thread has additional replies. If true, a call can be made to the `getPostThreadOtherV2` endpoint to retrieve them. */
|
|
43
|
+
hasOtherReplies: boolean
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export type HandlerInput = undefined
|
package/src/views/index.ts
CHANGED
|
@@ -59,7 +59,7 @@ import {
|
|
|
59
59
|
isRecord as isLabelerRecord,
|
|
60
60
|
} from '../lexicon/types/app/bsky/labeler/service'
|
|
61
61
|
import { RecordDeleted as NotificationRecordDeleted } from '../lexicon/types/app/bsky/notification/defs'
|
|
62
|
-
import {
|
|
62
|
+
import { ThreadItem as ThreadOtherItem } from '../lexicon/types/app/bsky/unspecced/getPostThreadOtherV2'
|
|
63
63
|
import {
|
|
64
64
|
QueryParams as GetPostThreadV2QueryParams,
|
|
65
65
|
ThreadItem,
|
|
@@ -75,13 +75,13 @@ import {
|
|
|
75
75
|
uriToDid as creatorFromUri,
|
|
76
76
|
} from '../util/uris'
|
|
77
77
|
import {
|
|
78
|
-
ThreadHiddenAnchorPostNode,
|
|
79
|
-
ThreadHiddenItemValuePost,
|
|
80
|
-
ThreadHiddenPostNode,
|
|
81
78
|
ThreadItemValueBlocked,
|
|
82
79
|
ThreadItemValueNoUnauthenticated,
|
|
83
80
|
ThreadItemValueNotFound,
|
|
84
81
|
ThreadItemValuePost,
|
|
82
|
+
ThreadOtherAnchorPostNode,
|
|
83
|
+
ThreadOtherItemValuePost,
|
|
84
|
+
ThreadOtherPostNode,
|
|
85
85
|
ThreadTree,
|
|
86
86
|
ThreadTreeVisible,
|
|
87
87
|
sortTrimFlattenThreadTree,
|
|
@@ -1161,7 +1161,7 @@ export class Views {
|
|
|
1161
1161
|
prioritizeFollowedUsers: boolean
|
|
1162
1162
|
sort: GetPostThreadV2QueryParams['sort']
|
|
1163
1163
|
},
|
|
1164
|
-
): {
|
|
1164
|
+
): { hasOtherReplies: boolean; thread: ThreadItem[] } {
|
|
1165
1165
|
const { anchor: anchorUri, uris } = skeleton
|
|
1166
1166
|
|
|
1167
1167
|
// Not found.
|
|
@@ -1169,7 +1169,7 @@ export class Views {
|
|
|
1169
1169
|
const post = state.posts?.get(anchorUri)
|
|
1170
1170
|
if (!post || !postView) {
|
|
1171
1171
|
return {
|
|
1172
|
-
|
|
1172
|
+
hasOtherReplies: false,
|
|
1173
1173
|
thread: [
|
|
1174
1174
|
this.threadV2ItemNotFound({
|
|
1175
1175
|
uri: anchorUri,
|
|
@@ -1182,7 +1182,7 @@ export class Views {
|
|
|
1182
1182
|
// Blocked (only 1p for anchor).
|
|
1183
1183
|
if (this.viewerBlockExists(postView.author.did, state)) {
|
|
1184
1184
|
return {
|
|
1185
|
-
|
|
1185
|
+
hasOtherReplies: false,
|
|
1186
1186
|
thread: [
|
|
1187
1187
|
this.threadV2ItemBlocked({
|
|
1188
1188
|
uri: anchorUri,
|
|
@@ -1229,7 +1229,7 @@ export class Views {
|
|
|
1229
1229
|
|
|
1230
1230
|
const anchorDepth = 0 // The depth of the anchor post is always 0.
|
|
1231
1231
|
let anchorTree: ThreadTree
|
|
1232
|
-
let
|
|
1232
|
+
let hasOtherReplies = false
|
|
1233
1233
|
|
|
1234
1234
|
if (this.noUnauthenticatedPost(state, postView)) {
|
|
1235
1235
|
anchorTree = {
|
|
@@ -1241,7 +1241,7 @@ export class Views {
|
|
|
1241
1241
|
parent,
|
|
1242
1242
|
}
|
|
1243
1243
|
} else {
|
|
1244
|
-
const { replies,
|
|
1244
|
+
const { replies, hasOtherReplies: hasOtherRepliesShadow } =
|
|
1245
1245
|
!anchorViolatesThreadGate
|
|
1246
1246
|
? this.threadV2Replies(
|
|
1247
1247
|
{
|
|
@@ -1257,8 +1257,8 @@ export class Views {
|
|
|
1257
1257
|
},
|
|
1258
1258
|
state,
|
|
1259
1259
|
)
|
|
1260
|
-
: { replies: undefined,
|
|
1261
|
-
|
|
1260
|
+
: { replies: undefined, hasOtherReplies: false }
|
|
1261
|
+
hasOtherReplies = hasOtherRepliesShadow
|
|
1262
1262
|
|
|
1263
1263
|
anchorTree = {
|
|
1264
1264
|
type: 'post',
|
|
@@ -1287,7 +1287,7 @@ export class Views {
|
|
|
1287
1287
|
})
|
|
1288
1288
|
|
|
1289
1289
|
return {
|
|
1290
|
-
|
|
1290
|
+
hasOtherReplies,
|
|
1291
1291
|
thread,
|
|
1292
1292
|
}
|
|
1293
1293
|
}
|
|
@@ -1432,14 +1432,14 @@ export class Views {
|
|
|
1432
1432
|
prioritizeFollowedUsers: boolean
|
|
1433
1433
|
},
|
|
1434
1434
|
state: HydrationState,
|
|
1435
|
-
): { replies: ThreadTreeVisible[] | undefined;
|
|
1435
|
+
): { replies: ThreadTreeVisible[] | undefined; hasOtherReplies: boolean } {
|
|
1436
1436
|
// Reached the `below` limit.
|
|
1437
1437
|
if (depth > below) {
|
|
1438
|
-
return { replies: undefined,
|
|
1438
|
+
return { replies: undefined, hasOtherReplies: false }
|
|
1439
1439
|
}
|
|
1440
1440
|
|
|
1441
1441
|
const childrenUris = childrenByParentUri[parentUri] ?? []
|
|
1442
|
-
let
|
|
1442
|
+
let hasOtherReplies = false
|
|
1443
1443
|
const replies = mapDefined(childrenUris, (uri) => {
|
|
1444
1444
|
const replyInclusion = this.checkThreadV2ReplyInclusion({
|
|
1445
1445
|
uri,
|
|
@@ -1452,14 +1452,14 @@ export class Views {
|
|
|
1452
1452
|
const { authorDid, post, postView } = replyInclusion
|
|
1453
1453
|
|
|
1454
1454
|
// Hidden.
|
|
1455
|
-
const {
|
|
1455
|
+
const { isOther } = this.isOtherThreadPost(
|
|
1456
1456
|
{ post, postView, prioritizeFollowedUsers, rootUri, uri },
|
|
1457
1457
|
state,
|
|
1458
1458
|
)
|
|
1459
|
-
if (
|
|
1459
|
+
if (isOther) {
|
|
1460
1460
|
// Only care about anchor replies
|
|
1461
1461
|
if (depth === 1) {
|
|
1462
|
-
|
|
1462
|
+
hasOtherReplies = true
|
|
1463
1463
|
}
|
|
1464
1464
|
return undefined
|
|
1465
1465
|
}
|
|
@@ -1504,7 +1504,7 @@ export class Views {
|
|
|
1504
1504
|
|
|
1505
1505
|
return {
|
|
1506
1506
|
replies,
|
|
1507
|
-
|
|
1507
|
+
hasOtherReplies,
|
|
1508
1508
|
}
|
|
1509
1509
|
}
|
|
1510
1510
|
|
|
@@ -1537,8 +1537,8 @@ export class Views {
|
|
|
1537
1537
|
moreParents: moreParents ?? false,
|
|
1538
1538
|
moreReplies,
|
|
1539
1539
|
opThread: isOPThread,
|
|
1540
|
-
hiddenByThreadgate: false, // Hidden posts are handled by
|
|
1541
|
-
mutedByViewer: false, // Hidden posts are handled by
|
|
1540
|
+
hiddenByThreadgate: false, // Hidden posts are handled by threadOtherV2
|
|
1541
|
+
mutedByViewer: false, // Hidden posts are handled by threadOtherV2
|
|
1542
1542
|
},
|
|
1543
1543
|
}
|
|
1544
1544
|
}
|
|
@@ -1599,7 +1599,7 @@ export class Views {
|
|
|
1599
1599
|
}
|
|
1600
1600
|
}
|
|
1601
1601
|
|
|
1602
|
-
|
|
1602
|
+
threadOtherV2(
|
|
1603
1603
|
skeleton: { anchor: string; uris: string[] },
|
|
1604
1604
|
state: HydrationState,
|
|
1605
1605
|
{
|
|
@@ -1611,7 +1611,7 @@ export class Views {
|
|
|
1611
1611
|
branchingFactor: number
|
|
1612
1612
|
prioritizeFollowedUsers: boolean
|
|
1613
1613
|
},
|
|
1614
|
-
):
|
|
1614
|
+
): ThreadOtherItem[] {
|
|
1615
1615
|
const { anchor: anchorUri, uris } = skeleton
|
|
1616
1616
|
|
|
1617
1617
|
// Not found.
|
|
@@ -1634,10 +1634,10 @@ export class Views {
|
|
|
1634
1634
|
const rootUri = getRootUri(anchorUri, post)
|
|
1635
1635
|
const opDid = uriToDid(rootUri)
|
|
1636
1636
|
|
|
1637
|
-
const anchorTree:
|
|
1637
|
+
const anchorTree: ThreadOtherAnchorPostNode = {
|
|
1638
1638
|
type: 'hiddenAnchor',
|
|
1639
|
-
item: this.
|
|
1640
|
-
replies: this.
|
|
1639
|
+
item: this.threadOtherV2ItemPostAnchor({ depth: 0, uri: anchorUri }),
|
|
1640
|
+
replies: this.threadOtherV2Replies(
|
|
1641
1641
|
{
|
|
1642
1642
|
parentUri: anchorUri,
|
|
1643
1643
|
rootUri,
|
|
@@ -1660,7 +1660,7 @@ export class Views {
|
|
|
1660
1660
|
})
|
|
1661
1661
|
}
|
|
1662
1662
|
|
|
1663
|
-
private
|
|
1663
|
+
private threadOtherV2Replies(
|
|
1664
1664
|
{
|
|
1665
1665
|
parentUri,
|
|
1666
1666
|
rootUri,
|
|
@@ -1677,7 +1677,7 @@ export class Views {
|
|
|
1677
1677
|
prioritizeFollowedUsers: boolean
|
|
1678
1678
|
},
|
|
1679
1679
|
state: HydrationState,
|
|
1680
|
-
):
|
|
1680
|
+
): ThreadOtherPostNode[] | undefined {
|
|
1681
1681
|
// Reached the `below` limit.
|
|
1682
1682
|
if (depth > below) {
|
|
1683
1683
|
return undefined
|
|
@@ -1695,13 +1695,13 @@ export class Views {
|
|
|
1695
1695
|
}
|
|
1696
1696
|
const { post, postView } = replyInclusion
|
|
1697
1697
|
|
|
1698
|
-
//
|
|
1699
|
-
const {
|
|
1700
|
-
this.
|
|
1698
|
+
// Other posts to pull out
|
|
1699
|
+
const { isOther, hiddenByThreadgate, mutedByViewer } =
|
|
1700
|
+
this.isOtherThreadPost(
|
|
1701
1701
|
{ post, postView, rootUri, prioritizeFollowedUsers, uri },
|
|
1702
1702
|
state,
|
|
1703
1703
|
)
|
|
1704
|
-
if (
|
|
1704
|
+
if (isOther) {
|
|
1705
1705
|
// Only show hidden anchor replies, not all hidden.
|
|
1706
1706
|
if (depth > 1) {
|
|
1707
1707
|
return undefined
|
|
@@ -1712,7 +1712,7 @@ export class Views {
|
|
|
1712
1712
|
}
|
|
1713
1713
|
|
|
1714
1714
|
// Recurse down.
|
|
1715
|
-
const replies = this.
|
|
1715
|
+
const replies = this.threadOtherV2Replies(
|
|
1716
1716
|
{
|
|
1717
1717
|
parentUri: uri,
|
|
1718
1718
|
rootUri,
|
|
@@ -1724,7 +1724,7 @@ export class Views {
|
|
|
1724
1724
|
state,
|
|
1725
1725
|
)
|
|
1726
1726
|
|
|
1727
|
-
const item = this.
|
|
1727
|
+
const item = this.threadOtherV2ItemPost({
|
|
1728
1728
|
depth,
|
|
1729
1729
|
hiddenByThreadgate,
|
|
1730
1730
|
mutedByViewer,
|
|
@@ -1732,7 +1732,7 @@ export class Views {
|
|
|
1732
1732
|
uri,
|
|
1733
1733
|
})
|
|
1734
1734
|
|
|
1735
|
-
const tree:
|
|
1735
|
+
const tree: ThreadOtherPostNode = {
|
|
1736
1736
|
type: 'hiddenPost',
|
|
1737
1737
|
item: item,
|
|
1738
1738
|
tags: post.tags,
|
|
@@ -1743,13 +1743,13 @@ export class Views {
|
|
|
1743
1743
|
})
|
|
1744
1744
|
}
|
|
1745
1745
|
|
|
1746
|
-
private
|
|
1746
|
+
private threadOtherV2ItemPostAnchor({
|
|
1747
1747
|
depth,
|
|
1748
1748
|
uri,
|
|
1749
1749
|
}: {
|
|
1750
1750
|
depth: number
|
|
1751
1751
|
uri: string
|
|
1752
|
-
}):
|
|
1752
|
+
}): ThreadOtherAnchorPostNode['item'] {
|
|
1753
1753
|
return {
|
|
1754
1754
|
uri,
|
|
1755
1755
|
depth,
|
|
@@ -1759,7 +1759,7 @@ export class Views {
|
|
|
1759
1759
|
}
|
|
1760
1760
|
}
|
|
1761
1761
|
|
|
1762
|
-
private
|
|
1762
|
+
private threadOtherV2ItemPost({
|
|
1763
1763
|
depth,
|
|
1764
1764
|
hiddenByThreadgate,
|
|
1765
1765
|
mutedByViewer,
|
|
@@ -1771,8 +1771,8 @@ export class Views {
|
|
|
1771
1771
|
mutedByViewer: boolean
|
|
1772
1772
|
postView: PostView
|
|
1773
1773
|
uri: string
|
|
1774
|
-
}):
|
|
1775
|
-
const base = this.
|
|
1774
|
+
}): ThreadOtherItemValuePost {
|
|
1775
|
+
const base = this.threadOtherV2ItemPostAnchor({ depth, uri })
|
|
1776
1776
|
return {
|
|
1777
1777
|
...base,
|
|
1778
1778
|
value: {
|
|
@@ -1780,9 +1780,9 @@ export class Views {
|
|
|
1780
1780
|
post: postView,
|
|
1781
1781
|
hiddenByThreadgate,
|
|
1782
1782
|
mutedByViewer,
|
|
1783
|
-
moreParents: false, //
|
|
1784
|
-
moreReplies: 0, //
|
|
1785
|
-
opThread: false, //
|
|
1783
|
+
moreParents: false, // "Other" replies don't have parents.
|
|
1784
|
+
moreReplies: 0, // "Other" replies don't have replies hydrated.
|
|
1785
|
+
opThread: false, // "Other" replies don't contain OP threads.
|
|
1786
1786
|
},
|
|
1787
1787
|
}
|
|
1788
1788
|
}
|
|
@@ -1834,7 +1834,7 @@ export class Views {
|
|
|
1834
1834
|
return { authorDid, post, postView }
|
|
1835
1835
|
}
|
|
1836
1836
|
|
|
1837
|
-
private
|
|
1837
|
+
private isOtherThreadPost(
|
|
1838
1838
|
{
|
|
1839
1839
|
post,
|
|
1840
1840
|
postView,
|
|
@@ -1850,7 +1850,7 @@ export class Views {
|
|
|
1850
1850
|
},
|
|
1851
1851
|
state: HydrationState,
|
|
1852
1852
|
): {
|
|
1853
|
-
|
|
1853
|
+
isOther: boolean
|
|
1854
1854
|
hiddenByTag: boolean
|
|
1855
1855
|
hiddenByThreadgate: boolean
|
|
1856
1856
|
mutedByViewer: boolean
|
|
@@ -1873,7 +1873,7 @@ export class Views {
|
|
|
1873
1873
|
const mutedByViewer = this.viewerMuteExists(authorDid, state)
|
|
1874
1874
|
|
|
1875
1875
|
return {
|
|
1876
|
-
|
|
1876
|
+
isOther: hiddenByTag || hiddenByThreadgate || mutedByViewer,
|
|
1877
1877
|
hiddenByTag,
|
|
1878
1878
|
hiddenByThreadgate,
|
|
1879
1879
|
mutedByViewer,
|
package/src/views/threads-v2.ts
CHANGED
|
@@ -7,18 +7,18 @@ import {
|
|
|
7
7
|
ThreadItemNotFound,
|
|
8
8
|
ThreadItemPost,
|
|
9
9
|
} from '../lexicon/types/app/bsky/unspecced/defs'
|
|
10
|
-
import {
|
|
10
|
+
import { ThreadItem as ThreadOtherItem } from '../lexicon/types/app/bsky/unspecced/getPostThreadOtherV2'
|
|
11
11
|
import {
|
|
12
12
|
QueryParams as GetPostThreadV2QueryParams,
|
|
13
13
|
ThreadItem,
|
|
14
14
|
} from '../lexicon/types/app/bsky/unspecced/getPostThreadV2'
|
|
15
15
|
import { $Typed } from '../lexicon/util'
|
|
16
16
|
|
|
17
|
-
type
|
|
17
|
+
type ThreadMaybeOtherPostNode = ThreadPostNode | ThreadOtherPostNode
|
|
18
18
|
type ThreadNodeWithReplies =
|
|
19
19
|
| ThreadPostNode
|
|
20
|
-
|
|
|
21
|
-
|
|
|
20
|
+
| ThreadOtherPostNode
|
|
21
|
+
| ThreadOtherAnchorPostNode
|
|
22
22
|
|
|
23
23
|
type ThreadItemValue<T extends ThreadItem['value']> = Omit<
|
|
24
24
|
ThreadItem,
|
|
@@ -63,37 +63,37 @@ type ThreadPostNode = {
|
|
|
63
63
|
replies: ThreadTree[] | undefined
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
type
|
|
67
|
-
|
|
66
|
+
type ThreadOtherItemValue<T extends ThreadOtherItem['value']> = Omit<
|
|
67
|
+
ThreadOtherItem,
|
|
68
68
|
'value'
|
|
69
69
|
> & {
|
|
70
70
|
value: T
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
export type
|
|
73
|
+
export type ThreadOtherItemValuePost = ThreadOtherItemValue<
|
|
74
74
|
$Typed<ThreadItemPost>
|
|
75
75
|
>
|
|
76
76
|
|
|
77
77
|
// This is an intermediary type that doesn't map to the views.
|
|
78
78
|
// It is useful to differentiate between the anchor post and the replies for the hidden case,
|
|
79
79
|
// while also differentiating between hidden and visible cases.
|
|
80
|
-
export type
|
|
80
|
+
export type ThreadOtherAnchorPostNode = {
|
|
81
81
|
type: 'hiddenAnchor'
|
|
82
|
-
item: Omit<
|
|
83
|
-
replies:
|
|
82
|
+
item: Omit<ThreadOtherItem, 'value'> & { value: undefined }
|
|
83
|
+
replies: ThreadOtherPostNode[] | undefined
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
export type
|
|
86
|
+
export type ThreadOtherPostNode = {
|
|
87
87
|
type: 'hiddenPost'
|
|
88
|
-
item:
|
|
88
|
+
item: ThreadOtherItemValuePost
|
|
89
89
|
tags: Set<string>
|
|
90
|
-
replies:
|
|
90
|
+
replies: ThreadOtherPostNode[] | undefined
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
const isNodeWithReplies = (node: ThreadTree): node is ThreadNodeWithReplies =>
|
|
94
94
|
'replies' in node && node.replies !== undefined
|
|
95
95
|
|
|
96
|
-
const isPostNode = (node: ThreadTree): node is
|
|
96
|
+
const isPostNode = (node: ThreadTree): node is ThreadMaybeOtherPostNode =>
|
|
97
97
|
node.type === 'post' || node.type === 'hiddenPost'
|
|
98
98
|
|
|
99
99
|
export type ThreadTreeVisible =
|
|
@@ -102,9 +102,9 @@ export type ThreadTreeVisible =
|
|
|
102
102
|
| ThreadNotFoundNode
|
|
103
103
|
| ThreadPostNode
|
|
104
104
|
|
|
105
|
-
export type
|
|
105
|
+
export type ThreadTreeOther = ThreadOtherAnchorPostNode | ThreadOtherPostNode
|
|
106
106
|
|
|
107
|
-
export type ThreadTree = ThreadTreeVisible |
|
|
107
|
+
export type ThreadTree = ThreadTreeVisible | ThreadTreeOther
|
|
108
108
|
|
|
109
109
|
/** This function mutates the tree parameter. */
|
|
110
110
|
export function sortTrimFlattenThreadTree(
|
|
@@ -146,8 +146,8 @@ function sortTrimThreadTree(
|
|
|
146
146
|
if (!isPostNode(bn)) {
|
|
147
147
|
return -1
|
|
148
148
|
}
|
|
149
|
-
const aNode:
|
|
150
|
-
const bNode:
|
|
149
|
+
const aNode: ThreadMaybeOtherPostNode = an
|
|
150
|
+
const bNode: ThreadMaybeOtherPostNode = bn
|
|
151
151
|
|
|
152
152
|
// First applies bumping.
|
|
153
153
|
const bump = applyBumping(aNode, bNode, opts)
|
|
@@ -171,8 +171,8 @@ function sortTrimThreadTree(
|
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
function applyBumping(
|
|
174
|
-
aNode:
|
|
175
|
-
bNode:
|
|
174
|
+
aNode: ThreadMaybeOtherPostNode,
|
|
175
|
+
bNode: ThreadMaybeOtherPostNode,
|
|
176
176
|
opts: SortTrimFlattenOptions,
|
|
177
177
|
): number | null {
|
|
178
178
|
if (!isPostNode(aNode)) {
|
|
@@ -191,7 +191,7 @@ function applyBumping(
|
|
|
191
191
|
} = opts
|
|
192
192
|
|
|
193
193
|
type BumpDirection = 'up' | 'down'
|
|
194
|
-
type BumpPredicateFn = (i:
|
|
194
|
+
type BumpPredicateFn = (i: ThreadMaybeOtherPostNode) => boolean
|
|
195
195
|
|
|
196
196
|
const maybeBump = (
|
|
197
197
|
bump: BumpDirection,
|
|
@@ -276,8 +276,8 @@ function applyBumping(
|
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
function applySorting(
|
|
279
|
-
aNode:
|
|
280
|
-
bNode:
|
|
279
|
+
aNode: ThreadMaybeOtherPostNode,
|
|
280
|
+
bNode: ThreadMaybeOtherPostNode,
|
|
281
281
|
opts: SortTrimFlattenOptions,
|
|
282
282
|
): number {
|
|
283
283
|
const a = aNode.item.value
|