Bluesky app fork with some witchin' additions 💫

demo mode

authored by samuel.fm and committed by

Eric Bailey 91f9bc7c c34c67e4

+616 -21
+20
src/lib/api/feed/demo.ts
··· 1 + import {type AppBskyFeedDefs, type BskyAgent} from '@atproto/api' 2 + 3 + import {DEMO_FEED} from '#/lib/demo' 4 + import {type FeedAPI, type FeedAPIResponse} from './types' 5 + 6 + export class DemoFeedAPI implements FeedAPI { 7 + agent: BskyAgent 8 + 9 + constructor({agent}: {agent: BskyAgent}) { 10 + this.agent = agent 11 + } 12 + 13 + async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> { 14 + return DEMO_FEED.feed[0] 15 + } 16 + 17 + async fetch(): Promise<FeedAPIResponse> { 18 + return DEMO_FEED 19 + } 20 + }
+516
src/lib/demo.ts
··· 1 + import {type AppBskyFeedGetFeed} from '@atproto/api' 2 + 3 + export const DEMO_FEED = { 4 + feed: [ 5 + { 6 + post: { 7 + uri: 'at://did:plc:vwzwgnygau7ed7b7wt5ux7y2/app.bsky.feed.post/3lng6kvb6uc2a', 8 + cid: 'bafyreifqyej7jivzucaagu22f7jj7rvjcpbzv2kxo27wt47ktduwwdpdae', 9 + author: { 10 + did: 'did:plc:vwzwgnygau7ed7b7wt5ux7y2', 11 + handle: 'someoneelse.bsky.social', 12 + displayName: 'Not David', 13 + avatar: 14 + 'https://cdn.bsky.app/img/avatar/plain/did:plc:vwzwgnygau7ed7b7wt5ux7y2/bafkreifrtz3ngpzz5qmhjliv5toj4nvyjovijxs5e2la67wddhmdhro5he@jpeg', 15 + associated: { 16 + chat: { 17 + allowIncoming: 'following', 18 + }, 19 + }, 20 + viewer: { 21 + muted: false, 22 + blockedBy: false, 23 + following: 24 + 'at://did:plc:p2cp5gopk7mgjegy6wadk3ep/app.bsky.graph.follow/3kcvvfzq6o32a', 25 + followedBy: 26 + 'at://did:plc:vwzwgnygau7ed7b7wt5ux7y2/app.bsky.graph.follow/3jwawchotz22h', 27 + }, 28 + labels: [], 29 + createdAt: '2023-04-27T09:23:54.423Z', 30 + verification: { 31 + verifications: [ 32 + { 33 + issuer: 'did:plc:z72i7hdynmk6r22z27h6tvur', 34 + uri: 'at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.graph.verification/3lndpxt7ur22f', 35 + isValid: true, 36 + createdAt: '2025-04-21T10:48:58.775Z', 37 + }, 38 + ], 39 + verifiedStatus: 'valid', 40 + trustedVerifierStatus: 'none', 41 + }, 42 + }, 43 + record: { 44 + $type: 'app.bsky.feed.post', 45 + createdAt: '2025-04-22T17:15:30.525Z', 46 + langs: ['en'], 47 + reply: { 48 + parent: { 49 + cid: 'bafyreic7wmhywvu5fi4lupswxpmyydqn2gl5kwnt4n4jxvb3lpej2l72ku', 50 + uri: 'at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lng66dkzu222', 51 + }, 52 + root: { 53 + cid: 'bafyreic7wmhywvu5fi4lupswxpmyydqn2gl5kwnt4n4jxvb3lpej2l72ku', 54 + uri: 'at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lng66dkzu222', 55 + }, 56 + }, 57 + text: 'sometimes I go to the apple store just to look at them', 58 + }, 59 + replyCount: 0, 60 + repostCount: 0, 61 + likeCount: 6, 62 + quoteCount: 0, 63 + indexedAt: '2025-04-22T17:15:31.251Z', 64 + viewer: { 65 + threadMuted: false, 66 + embeddingDisabled: false, 67 + }, 68 + labels: [], 69 + }, 70 + reply: { 71 + root: { 72 + uri: 'at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lng66dkzu222', 73 + cid: 'bafyreic7wmhywvu5fi4lupswxpmyydqn2gl5kwnt4n4jxvb3lpej2l72ku', 74 + author: { 75 + did: 'did:plc:vc7f4oafdgxsihk4cry2xpze', 76 + handle: 'jasalterego.bsky.social', 77 + displayName: 'Jerry Appleseed', 78 + avatar: 79 + 'https://cdn.bsky.app/img/avatar/plain/did:plc:vc7f4oafdgxsihk4cry2xpze/bafkreicwxwecqiko2rwwln5y3fqqb2zx6wfg5rxf5r7lukakkq2slqy5hy@jpeg', 80 + associated: { 81 + chat: { 82 + allowIncoming: 'following', 83 + }, 84 + }, 85 + viewer: { 86 + muted: false, 87 + blockedBy: false, 88 + following: 89 + 'at://did:plc:p2cp5gopk7mgjegy6wadk3ep/app.bsky.graph.follow/3jx4rnvlnhl25', 90 + followedBy: 91 + 'at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.graph.follow/3jx4siiniuc2e', 92 + }, 93 + labels: [ 94 + { 95 + cts: '2024-05-17T21:53:59.049Z', 96 + src: 'did:plc:skibpmllbhxvbvwgtjxl3uao', 97 + uri: 'did:plc:vc7f4oafdgxsihk4cry2xpze', 98 + val: 'cringe', 99 + ver: 1, 100 + }, 101 + { 102 + cts: '2024-05-17T21:53:59.049Z', 103 + src: 'did:plc:skibpmllbhxvbvwgtjxl3uao', 104 + uri: 'did:plc:vc7f4oafdgxsihk4cry2xpze', 105 + val: 'elder-watch', 106 + ver: 1, 107 + }, 108 + { 109 + src: 'did:plc:vc7f4oafdgxsihk4cry2xpze', 110 + uri: 'at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.actor.profile/self', 111 + cid: 'bafyreidfiuv3c22vliyu2onazf23zrp35rr7i3upsqa2dsn5cqimmlgugm', 112 + val: '!no-unauthenticated', 113 + cts: '1970-01-01T00:00:00.000Z', 114 + }, 115 + ], 116 + createdAt: '2023-04-23T20:11:04.375Z', 117 + }, 118 + record: { 119 + $type: 'app.bsky.feed.post', 120 + createdAt: '2025-04-22T17:08:29.321Z', 121 + langs: ['en'], 122 + text: "(studying the blade) ow that's the sharp side", 123 + }, 124 + replyCount: 8, 125 + repostCount: 37, 126 + likeCount: 252, 127 + quoteCount: 1, 128 + indexedAt: '2025-04-22T17:08:29.458Z', 129 + viewer: { 130 + threadMuted: false, 131 + embeddingDisabled: false, 132 + }, 133 + labels: [], 134 + $type: 'app.bsky.feed.defs#postView', 135 + }, 136 + parent: { 137 + uri: 'at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lng66dkzu222', 138 + cid: 'bafyreic7wmhywvu5fi4lupswxpmyydqn2gl5kwnt4n4jxvb3lpej2l72ku', 139 + author: { 140 + did: 'did:plc:vc7f4oafdgxsihk4cry2xpze', 141 + handle: 'jasalterego.bsky.social', 142 + displayName: 'Jerry Appleseed', 143 + avatar: 144 + 'https://cdn.bsky.app/img/avatar/plain/did:plc:vc7f4oafdgxsihk4cry2xpze/bafkreicwxwecqiko2rwwln5y3fqqb2zx6wfg5rxf5r7lukakkq2slqy5hy@jpeg', 145 + associated: { 146 + chat: { 147 + allowIncoming: 'following', 148 + }, 149 + }, 150 + viewer: { 151 + muted: false, 152 + blockedBy: false, 153 + following: 154 + 'at://did:plc:p2cp5gopk7mgjegy6wadk3ep/app.bsky.graph.follow/3jx4rnvlnhl25', 155 + followedBy: 156 + 'at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.graph.follow/3jx4siiniuc2e', 157 + }, 158 + labels: [ 159 + { 160 + cts: '2024-05-17T21:53:59.049Z', 161 + src: 'did:plc:skibpmllbhxvbvwgtjxl3uao', 162 + uri: 'did:plc:vc7f4oafdgxsihk4cry2xpze', 163 + val: 'cringe', 164 + ver: 1, 165 + }, 166 + { 167 + cts: '2024-05-17T21:53:59.049Z', 168 + src: 'did:plc:skibpmllbhxvbvwgtjxl3uao', 169 + uri: 'did:plc:vc7f4oafdgxsihk4cry2xpze', 170 + val: 'elder-watch', 171 + ver: 1, 172 + }, 173 + { 174 + src: 'did:plc:vc7f4oafdgxsihk4cry2xpze', 175 + uri: 'at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.actor.profile/self', 176 + cid: 'bafyreidfiuv3c22vliyu2onazf23zrp35rr7i3upsqa2dsn5cqimmlgugm', 177 + val: '!no-unauthenticated', 178 + cts: '1970-01-01T00:00:00.000Z', 179 + }, 180 + ], 181 + createdAt: '2023-04-23T20:11:04.375Z', 182 + }, 183 + record: { 184 + $type: 'app.bsky.feed.post', 185 + createdAt: '2025-04-22T17:08:29.321Z', 186 + langs: ['en'], 187 + text: '*sees the studio display* i think i hauve covid', 188 + }, 189 + replyCount: 8, 190 + repostCount: 37, 191 + likeCount: 252, 192 + quoteCount: 1, 193 + indexedAt: '2025-04-22T17:08:29.458Z', 194 + viewer: { 195 + threadMuted: false, 196 + embeddingDisabled: false, 197 + }, 198 + labels: [], 199 + $type: 'app.bsky.feed.defs#postView', 200 + }, 201 + }, 202 + }, 203 + { 204 + post: { 205 + uri: 'at://did:plc:qvzn322kmcvd7xtnips5xaun/app.bsky.feed.post/3lnehbwkvzk2z', 206 + cid: 'bafyreidshyla4xoolb7fexhtlqcjjbn6ts7z4xja7gnlinroms5cuqg3fq', 207 + author: { 208 + did: 'did:plc:qvzn322kmcvd7xtnips5xaun', 209 + handle: 'scalzi.com', 210 + displayName: 'John Scalzi', 211 + avatar: 212 + 'https://cdn.bsky.app/img/avatar/plain/did:plc:qvzn322kmcvd7xtnips5xaun/bafkreih4dn5gllculyzb6wlqcqparkax35zloe3bzn2nufeqeilz4sutsu@jpeg', 213 + associated: { 214 + chat: { 215 + allowIncoming: 'following', 216 + }, 217 + }, 218 + 219 + viewer: { 220 + muted: false, 221 + blockedBy: false, 222 + following: 223 + 'at://did:plc:p2cp5gopk7mgjegy6wadk3ep/app.bsky.graph.follow/3kcvvfzq6o32a', 224 + followedBy: 225 + 'at://did:plc:vwzwgnygau7ed7b7wt5ux7y2/app.bsky.graph.follow/3jwawchotz22h', 226 + }, 227 + labels: [], 228 + createdAt: '2023-04-27T16:05:17.859Z', 229 + }, 230 + record: { 231 + $type: 'app.bsky.feed.post', 232 + createdAt: '2025-04-22T00:46:14.095Z', 233 + embed: { 234 + $type: 'app.bsky.embed.images', 235 + images: [ 236 + { 237 + alt: 'Smudge napping on the Eames chair, which is covered in a blanket to avoid getting cat hair on it. ', 238 + aspectRatio: { 239 + height: 2000, 240 + width: 1505, 241 + }, 242 + image: { 243 + $type: 'blob', 244 + ref: { 245 + $link: 246 + 'bafkreigkfbcmttc4r4avknp4y2mlcjlws3sdcat6jcyd2mjr7yvz6sje4q', 247 + }, 248 + mimeType: 'image/jpeg', 249 + size: 833834, 250 + }, 251 + }, 252 + ], 253 + }, 254 + langs: ['en'], 255 + text: 'Smudge found the Eames chair', 256 + }, 257 + embed: { 258 + $type: 'app.bsky.embed.images#view', 259 + images: [ 260 + { 261 + thumb: 262 + 'https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:qvzn322kmcvd7xtnips5xaun/bafkreigkfbcmttc4r4avknp4y2mlcjlws3sdcat6jcyd2mjr7yvz6sje4q@jpeg', 263 + fullsize: 264 + 'https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:qvzn322kmcvd7xtnips5xaun/bafkreigkfbcmttc4r4avknp4y2mlcjlws3sdcat6jcyd2mjr7yvz6sje4q@jpeg', 265 + alt: 'Smudge napping on the Eames chair, which is covered in a blanket to avoid getting cat hair on it. ', 266 + aspectRatio: { 267 + height: 2000, 268 + width: 1505, 269 + }, 270 + }, 271 + ], 272 + }, 273 + replyCount: 47, 274 + repostCount: 31, 275 + likeCount: 1543, 276 + quoteCount: 0, 277 + indexedAt: '2025-04-22T00:46:17.457Z', 278 + viewer: { 279 + threadMuted: false, 280 + embeddingDisabled: false, 281 + }, 282 + labels: [], 283 + }, 284 + }, 285 + { 286 + post: { 287 + uri: 'at://did:plc:jb2q4yqmgpmefxd4xx66gepm/app.bsky.feed.post/3lng4m2memc2k', 288 + cid: 'bafyreicvgwkd5xkbtu3eh756yodnynqbxoegzzqhhees5ou45t3gq3j6um', 289 + author: { 290 + did: 'did:plc:jb2q4yqmgpmefxd4xx66gepm', 291 + handle: 'visionprofan.bsky.social', 292 + displayName: 'Visionary', 293 + avatar: 294 + 'https://cdn.bsky.app/img/avatar/plain/did:plc:jb2q4yqmgpmefxd4xx66gepm/bafkreibqdpwilgj43m37ksjilzcnzqx2g3njcyiyifvazdar23rs5hlokm@jpeg', 295 + associated: { 296 + chat: { 297 + allowIncoming: 'following', 298 + }, 299 + }, 300 + 301 + viewer: { 302 + muted: false, 303 + blockedBy: false, 304 + following: 305 + 'at://did:plc:p2cp5gopk7mgjegy6wadk3ep/app.bsky.graph.follow/3kcvvfzq6o32a', 306 + followedBy: 307 + 'at://did:plc:vwzwgnygau7ed7b7wt5ux7y2/app.bsky.graph.follow/3jwawchotz22h', 308 + }, 309 + labels: [ 310 + { 311 + cts: '2024-07-14T04:31:55.599Z', 312 + src: 'did:plc:skibpmllbhxvbvwgtjxl3uao', 313 + uri: 'did:plc:jb2q4yqmgpmefxd4xx66gepm', 314 + val: 'cringe', 315 + ver: 1, 316 + }, 317 + ], 318 + createdAt: '2023-04-13T05:48:48.827Z', 319 + }, 320 + record: { 321 + $type: 'app.bsky.feed.post', 322 + createdAt: '2025-04-22T16:40:22.205Z', 323 + embed: { 324 + $type: 'app.bsky.embed.record', 325 + record: { 326 + cid: 'bafyreif6ks7dhjrgrio5guztdhf3byoygbwebbvehi4al2c5kmkevlqdky', 327 + uri: 'at://did:plc:4llrhdclvdlmmynkwsmg5tdc/app.bsky.feed.post/3lnfspxzdd42p', 328 + }, 329 + }, 330 + langs: ['en'], 331 + text: 'Just got my Vision Pro! 🤯\n\nAny recommendations for apps to try out?', 332 + }, 333 + embed: { 334 + $type: 'app.bsky.embed.record#view', 335 + record: { 336 + $type: 'app.bsky.embed.record#viewRecord', 337 + uri: 'at://did:plc:4llrhdclvdlmmynkwsmg5tdc/app.bsky.feed.post/3lnfspxzdd42p', 338 + cid: 'bafyreif6ks7dhjrgrio5guztdhf3byoygbwebbvehi4al2c5kmkevlqdky', 339 + author: { 340 + did: 'did:plc:4llrhdclvdlmmynkwsmg5tdc', 341 + handle: 'atrupar.com', 342 + displayName: 'Aaron Rupar', 343 + avatar: 344 + 'https://cdn.bsky.app/img/avatar/plain/did:plc:4llrhdclvdlmmynkwsmg5tdc/bafkreibmhm3h6ar52pogvolisrzjdhwa2myras5vkxzj67twxn2l6pogwu@jpeg', 345 + associated: { 346 + chat: { 347 + allowIncoming: 'following', 348 + }, 349 + }, 350 + viewer: { 351 + muted: false, 352 + blockedBy: false, 353 + following: 354 + 'at://did:plc:p2cp5gopk7mgjegy6wadk3ep/app.bsky.graph.follow/3l7eals2t4g2k', 355 + }, 356 + labels: [], 357 + createdAt: '2023-04-28T00:47:57.437Z', 358 + }, 359 + value: { 360 + $type: 'app.bsky.feed.post', 361 + createdAt: '2025-04-22T13:43:36.261Z', 362 + embed: { 363 + $type: 'app.bsky.embed.video', 364 + alt: '', 365 + aspectRatio: { 366 + height: 720, 367 + width: 1280, 368 + }, 369 + captions: [ 370 + { 371 + $type: 'app.bsky.embed.video#caption', 372 + file: { 373 + $type: 'blob', 374 + ref: { 375 + $link: 376 + 'bafkreihm7npnefqxqmn7d45lcbxzn4wnowc2abe5hxmd63qlob7fbszola', 377 + }, 378 + mimeType: 'text/vtt', 379 + size: 1339, 380 + }, 381 + lang: 'en', 382 + }, 383 + ], 384 + video: { 385 + $type: 'blob', 386 + ref: { 387 + $link: 388 + 'bafkreihovdkyvql2yswuimm5m35lqyo7tgsfiujm7vrxtfmi4gwej4hkpa', 389 + }, 390 + mimeType: 'video/mp4', 391 + size: 6026932, 392 + }, 393 + }, 394 + facets: [], 395 + langs: ['en'], 396 + text: 'Austin Scott previews how House Rs plan to cut Medicaid: "The federal govt is paying 90% of the Medicaid expansion. What we\'ve talked about is moving that 90% level of the expansion back... nobody would be kicked off Medicaid as long as governors decided they wanted to continue to fund the program"', 397 + }, 398 + labels: [], 399 + likeCount: 880, 400 + replyCount: 230, 401 + repostCount: 347, 402 + quoteCount: 145, 403 + indexedAt: '2025-04-22T13:43:37.350Z', 404 + embeds: [ 405 + { 406 + $type: 'app.bsky.embed.video#view', 407 + cid: 'bafkreihovdkyvql2yswuimm5m35lqyo7tgsfiujm7vrxtfmi4gwej4hkpa', 408 + playlist: 409 + 'https://video.bsky.app/watch/did%3Aplc%3A4llrhdclvdlmmynkwsmg5tdc/bafkreihovdkyvql2yswuimm5m35lqyo7tgsfiujm7vrxtfmi4gwej4hkpa/playlist.m3u8', 410 + thumbnail: 411 + 'https://video.bsky.app/watch/did%3Aplc%3A4llrhdclvdlmmynkwsmg5tdc/bafkreihovdkyvql2yswuimm5m35lqyo7tgsfiujm7vrxtfmi4gwej4hkpa/thumbnail.jpg', 412 + alt: '', 413 + aspectRatio: { 414 + height: 720, 415 + width: 1280, 416 + }, 417 + }, 418 + ], 419 + }, 420 + }, 421 + replyCount: 11, 422 + repostCount: 97, 423 + likeCount: 399, 424 + quoteCount: 3, 425 + indexedAt: '2025-04-22T16:40:22.648Z', 426 + viewer: { 427 + threadMuted: false, 428 + embeddingDisabled: false, 429 + }, 430 + labels: [], 431 + }, 432 + }, 433 + { 434 + post: { 435 + uri: 'at://did:plc:5o6k7jvowuyaquloafzn3cfw/app.bsky.feed.post/3lng6lkuhxc2s', 436 + cid: 'bafyreifwapmjx76kz5lkoeejfoes4ct2xhyycfyxwccmyr3mtxht5juyli', 437 + author: { 438 + did: 'did:plc:5o6k7jvowuyaquloafzn3cfw', 439 + handle: 'johndoe.org', 440 + displayName: 'John Doe', 441 + avatar: 442 + 'https://cdn.bsky.app/img/avatar/plain/did:plc:5o6k7jvowuyaquloafzn3cfw/bafkreierrwtdsf5quwprs2xqmmh2lu2k7au2cibyegfpard6wqyjs7nd6i@jpeg', 443 + 444 + viewer: { 445 + muted: false, 446 + blockedBy: false, 447 + following: 448 + 'at://did:plc:p2cp5gopk7mgjegy6wadk3ep/app.bsky.graph.follow/3kcvvfzq6o32a', 449 + followedBy: 450 + 'at://did:plc:vwzwgnygau7ed7b7wt5ux7y2/app.bsky.graph.follow/3jwawchotz22h', 451 + }, 452 + labels: [], 453 + createdAt: '2023-05-16T02:37:39.269Z', 454 + }, 455 + record: { 456 + $type: 'app.bsky.feed.post', 457 + createdAt: '2025-04-22T17:15:53.178Z', 458 + langs: ['en'], 459 + text: "I'm running out of ideas for these fake posts. Alas, such is the demands of modern life. Do you like blueberries? Just remembered that blueberries are delicious! They're so tasty! I can't wait to try them!", 460 + }, 461 + replyCount: 13, 462 + repostCount: 121, 463 + likeCount: 345, 464 + quoteCount: 6, 465 + indexedAt: '2025-04-22T17:15:53.351Z', 466 + viewer: { 467 + threadMuted: false, 468 + embeddingDisabled: false, 469 + }, 470 + labels: [], 471 + }, 472 + }, 473 + { 474 + post: { 475 + uri: 'at://did:plc:5ywatwbfxoecxgb4xq6ods72/app.bsky.feed.post/3lng5w2fbvs2g', 476 + cid: 'bafyreigi7d57fudzoybe4u6w7friw6ydz3pmzrdu3bvjwb5mvsvlprk23y', 477 + author: { 478 + did: 'did:plc:5ywatwbfxoecxgb4xq6ods72', 479 + handle: 'cooking.bsky.social', 480 + displayName: 'cooking tips', 481 + avatar: 482 + 'https://cdn.bsky.app/img/avatar/plain/did:plc:5ywatwbfxoecxgb4xq6ods72/bafkreibbsuyy25elibbys5vx25cnkcs6g4ih6dozypa4bomwhkwsi6f5wa@jpeg', 483 + 484 + viewer: { 485 + muted: false, 486 + blockedBy: false, 487 + following: 488 + 'at://did:plc:p2cp5gopk7mgjegy6wadk3ep/app.bsky.graph.follow/3kcvvfzq6o32a', 489 + followedBy: 490 + 'at://did:plc:vwzwgnygau7ed7b7wt5ux7y2/app.bsky.graph.follow/3jwawchotz22h', 491 + }, 492 + labels: [], 493 + createdAt: '2024-05-28T00:18:08.531Z', 494 + }, 495 + record: { 496 + $type: 'app.bsky.feed.post', 497 + createdAt: '2025-04-22T17:03:51.259Z', 498 + langs: ['en'], 499 + text: 'and another thing. I have more things to say. I think. I forget :/', 500 + }, 501 + replyCount: 1, 502 + repostCount: 4, 503 + likeCount: 20, 504 + quoteCount: 0, 505 + indexedAt: '2025-04-22T17:03:52.050Z', 506 + viewer: { 507 + threadMuted: false, 508 + embeddingDisabled: false, 509 + }, 510 + labels: [], 511 + }, 512 + }, 513 + ], 514 + } satisfies AppBskyFeedGetFeed.OutputSchema 515 + 516 + export const BOTTOM_BAR_AVI = 'https://bsky.social/about/hero-social-card.webp'
+13 -9
src/state/queries/post-feed.ts
··· 1 1 import React, {useCallback, useEffect, useRef} from 'react' 2 2 import {AppState} from 'react-native' 3 3 import { 4 - AppBskyActorDefs, 4 + type AppBskyActorDefs, 5 5 AppBskyFeedDefs, 6 - AppBskyFeedPost, 6 + type AppBskyFeedPost, 7 7 AtUri, 8 - BskyAgent, 8 + type BskyAgent, 9 9 moderatePost, 10 - ModerationDecision, 10 + type ModerationDecision, 11 11 } from '@atproto/api' 12 12 import { 13 - InfiniteData, 14 - QueryClient, 15 - QueryKey, 13 + type InfiniteData, 14 + type QueryClient, 15 + type QueryKey, 16 16 useInfiniteQuery, 17 17 } from '@tanstack/react-query' 18 18 19 19 import {AuthorFeedAPI} from '#/lib/api/feed/author' 20 20 import {CustomFeedAPI} from '#/lib/api/feed/custom' 21 + import {DemoFeedAPI} from '#/lib/api/feed/demo' 21 22 import {FollowingFeedAPI} from '#/lib/api/feed/following' 22 23 import {HomeFeedAPI} from '#/lib/api/feed/home' 23 24 import {LikesFeedAPI} from '#/lib/api/feed/likes' 24 25 import {ListFeedAPI} from '#/lib/api/feed/list' 25 26 import {MergeFeedAPI} from '#/lib/api/feed/merge' 26 - import {FeedAPI, ReasonFeedSource} from '#/lib/api/feed/types' 27 + import {type FeedAPI, type ReasonFeedSource} from '#/lib/api/feed/types' 27 28 import {aggregateUserInterests} from '#/lib/api/feed/utils' 28 - import {FeedTuner, FeedTunerFn} from '#/lib/api/feed-manip' 29 + import {FeedTuner, type FeedTunerFn} from '#/lib/api/feed-manip' 29 30 import {DISCOVER_FEED_URI} from '#/lib/constants' 30 31 import {BSKY_FEED_OWNER_DIDS} from '#/lib/constants' 31 32 import {logger} from '#/logger' ··· 59 60 | `feedgen|${FeedUri}` 60 61 | `likes|${ActorDid}` 61 62 | `list|${ListUri}` 63 + | 'demo' 62 64 export interface FeedParams { 63 65 mergeFeedEnabled?: boolean 64 66 mergeFeedSources?: string[] ··· 483 485 } else if (feedDesc.startsWith('list')) { 484 486 const [_, list] = feedDesc.split('|') 485 487 return new ListFeedAPI({agent, feedParams: {list}}) 488 + } else if (feedDesc === 'demo') { 489 + return new DemoFeedAPI({agent}) 486 490 } else { 487 491 // shouldnt happen 488 492 return new FollowingFeedAPI({agent})
+58 -7
src/view/screens/Home.tsx
··· 8 8 import {useSetTitle} from '#/lib/hooks/useSetTitle' 9 9 import {useRequestNotificationsPermission} from '#/lib/notifications/notifications' 10 10 import { 11 - HomeTabNavigatorParams, 12 - NativeStackScreenProps, 11 + type HomeTabNavigatorParams, 12 + type NativeStackScreenProps, 13 13 } from '#/lib/routes/types' 14 14 import {logEvent} from '#/lib/statsig/statsig' 15 15 import {isWeb} from '#/platform/detection' 16 16 import {emitSoftReset} from '#/state/events' 17 - import {SavedFeedSourceInfo, usePinnedFeedsInfos} from '#/state/queries/feed' 18 - import {FeedDescriptor, FeedParams} from '#/state/queries/post-feed' 17 + import { 18 + type SavedFeedSourceInfo, 19 + usePinnedFeedsInfos, 20 + } from '#/state/queries/feed' 21 + import {type FeedDescriptor, type FeedParams} from '#/state/queries/post-feed' 19 22 import {usePreferencesQuery} from '#/state/queries/preferences' 20 - import {UsePreferencesQueryResponse} from '#/state/queries/preferences/types' 23 + import {type UsePreferencesQueryResponse} from '#/state/queries/preferences/types' 21 24 import {useSession} from '#/state/session' 22 25 import {useSetMinimalShellMode} from '#/state/shell' 23 26 import {useLoggedOutViewControls} from '#/state/shell/logged-out' 24 27 import {useSelectedFeed, useSetSelectedFeed} from '#/state/shell/selected-feed' 25 28 import {FeedPage} from '#/view/com/feeds/FeedPage' 26 29 import {HomeHeader} from '#/view/com/home/HomeHeader' 27 - import {Pager, PagerRef, RenderTabBarFnProps} from '#/view/com/pager/Pager' 30 + import { 31 + Pager, 32 + type PagerRef, 33 + type RenderTabBarFnProps, 34 + } from '#/view/com/pager/Pager' 28 35 import {CustomFeedEmptyState} from '#/view/com/posts/CustomFeedEmptyState' 29 36 import {FollowingEmptyState} from '#/view/com/posts/FollowingEmptyState' 30 37 import {FollowingEndOfFeed} from '#/view/com/posts/FollowingEndOfFeed' 31 38 import {NoFeedsPinned} from '#/screens/Home/NoFeedsPinned' 32 39 import * as Layout from '#/components/Layout' 40 + import {useDemoMode} from '#/storage/hooks/demo-mode' 33 41 34 42 type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home' | 'Start'> 35 43 export function HomeScreen(props: Props) { ··· 184 192 [setMinimalShellMode], 185 193 ) 186 194 195 + const [demoMode] = useDemoMode() 196 + 187 197 const renderTabBar = React.useCallback( 188 198 (props: RenderTabBarFnProps) => { 199 + if (demoMode) { 200 + return ( 201 + <HomeHeader 202 + key="FEEDS_TAB_BAR" 203 + {...props} 204 + testID="homeScreenFeedTabs" 205 + onPressSelected={onPressSelected} 206 + // @ts-ignore 207 + feeds={[{displayName: 'Following'}, {displayName: 'Discover'}]} 208 + /> 209 + ) 210 + } 189 211 return ( 190 212 <HomeHeader 191 213 key="FEEDS_TAB_BAR" ··· 196 218 /> 197 219 ) 198 220 }, 199 - [onPressSelected, pinnedFeedInfos], 221 + [onPressSelected, pinnedFeedInfos, demoMode], 200 222 ) 201 223 202 224 const renderFollowingEmptyState = React.useCallback(() => { ··· 217 239 : [], 218 240 } 219 241 }, [preferences]) 242 + 243 + if (demoMode) { 244 + return ( 245 + <Pager 246 + ref={pagerRef} 247 + testID="homeScreen" 248 + onPageSelected={onPageSelected} 249 + onPageScrollStateChanged={onPageScrollStateChanged} 250 + renderTabBar={renderTabBar} 251 + initialPage={selectedIndex}> 252 + <FeedPage 253 + testID="demoFeedPage" 254 + isPageFocused 255 + isPageAdjacent={false} 256 + feed="demo" 257 + renderEmptyState={renderCustomFeedEmptyState} 258 + feedInfo={pinnedFeedInfos[0]} 259 + /> 260 + <FeedPage 261 + testID="customFeedPage" 262 + isPageFocused 263 + isPageAdjacent={false} 264 + feed={`feedgen|${PROD_DEFAULT_FEED('whats-hot')}`} 265 + renderEmptyState={renderCustomFeedEmptyState} 266 + feedInfo={pinnedFeedInfos[0]} 267 + /> 268 + </Pager> 269 + ) 270 + } 220 271 221 272 return hasSession ? ( 222 273 <Pager
+9 -5
src/view/shell/bottom-bar/BottomBar.tsx
··· 1 - import React, {ComponentProps} from 'react' 2 - import {GestureResponderEvent, View} from 'react-native' 1 + import React, {type ComponentProps} from 'react' 2 + import {type GestureResponderEvent, View} from 'react-native' 3 3 import Animated from 'react-native-reanimated' 4 4 import {useSafeAreaInsets} from 'react-native-safe-area-context' 5 5 import {msg, plural, Trans} from '@lingui/macro' 6 6 import {useLingui} from '@lingui/react' 7 - import {BottomTabBarProps} from '@react-navigation/bottom-tabs' 7 + import {type BottomTabBarProps} from '@react-navigation/bottom-tabs' 8 8 import {StackActions} from '@react-navigation/native' 9 9 10 10 import {PressableScale} from '#/lib/custom-animations/PressableScale' 11 + import {BOTTOM_BAR_AVI} from '#/lib/demo' 11 12 import {useHaptics} from '#/lib/haptics' 12 13 import {useDedupe} from '#/lib/hooks/useDedupe' 13 14 import {useMinimalShellFooterTransform} from '#/lib/hooks/useMinimalShellTransform' ··· 47 48 Message_Stroke2_Corner0_Rounded as Message, 48 49 Message_Stroke2_Corner0_Rounded_Filled as MessageFilled, 49 50 } from '#/components/icons/Message' 51 + import {useDemoMode} from '#/storage/hooks/demo-mode' 50 52 import {styles} from './BottomBarStyles' 51 53 52 54 type TabOptions = ··· 123 125 playHaptic() 124 126 accountSwitchControl.open() 125 127 }, [accountSwitchControl, playHaptic]) 128 + 129 + const [demoMode] = useDemoMode() 126 130 127 131 return ( 128 132 <> ··· 259 263 {borderColor: pal.text.color}, 260 264 ]}> 261 265 <UserAvatar 262 - avatar={profile?.avatar} 266 + avatar={demoMode ? BOTTOM_BAR_AVI : profile?.avatar} 263 267 size={iconWidth - 3} 264 268 // See https://github.com/bluesky-social/social-app/pull/1801: 265 269 usePlainRNImage={true} ··· 270 274 <View 271 275 style={[styles.ctrlIcon, pal.text, styles.profileIcon]}> 272 276 <UserAvatar 273 - avatar={profile?.avatar} 277 + avatar={demoMode ? BOTTOM_BAR_AVI : profile?.avatar} 274 278 size={iconWidth - 3} 275 279 // See https://github.com/bluesky-social/social-app/pull/1801: 276 280 usePlainRNImage={true}