mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at profile-init 139 lines 3.8 kB view raw
1import {makeAutoObservable} from 'mobx' 2import { 3 AppBskyFeedPost as FeedPost, 4 AppBskyFeedDefs, 5 RichText, 6 PostModeration, 7} from '@atproto/api' 8import {RootStoreModel} from '../root-store' 9import {PostsFeedItemModel} from '../feeds/post' 10 11type PostView = AppBskyFeedDefs.PostView 12 13// NOTE: this model uses the same data as PostsFeedItemModel, but is used for 14// rendering a single post in a thread view, and has additional state 15// for rendering the thread view, but calls the same data methods 16// as PostsFeedItemModel 17// TODO: refactor as an extension or subclass of PostsFeedItemModel 18export class PostThreadItemModel { 19 // ui state 20 _reactKey: string = '' 21 _depth = 0 22 _isHighlightedPost = false 23 _showParentReplyLine = false 24 _showChildReplyLine = false 25 _hasMore = false 26 27 // data 28 data: PostsFeedItemModel 29 post: PostView 30 postRecord?: FeedPost.Record 31 richText?: RichText 32 parent?: 33 | PostThreadItemModel 34 | AppBskyFeedDefs.NotFoundPost 35 | AppBskyFeedDefs.BlockedPost 36 replies?: (PostThreadItemModel | AppBskyFeedDefs.NotFoundPost)[] 37 38 constructor( 39 public rootStore: RootStoreModel, 40 v: AppBskyFeedDefs.ThreadViewPost, 41 ) { 42 this._reactKey = `thread-${v.post.uri}` 43 this.data = new PostsFeedItemModel(rootStore, this._reactKey, v) 44 this.post = this.data.post 45 this.postRecord = this.data.postRecord 46 this.richText = this.data.richText 47 // replies and parent are handled via assignTreeModels 48 makeAutoObservable(this, {rootStore: false}) 49 } 50 51 get uri() { 52 return this.post.uri 53 } 54 55 get parentUri() { 56 return this.postRecord?.reply?.parent.uri 57 } 58 59 get rootUri(): string { 60 if (this.postRecord?.reply?.root.uri) { 61 return this.postRecord.reply.root.uri 62 } 63 return this.post.uri 64 } 65 66 get isThreadMuted() { 67 return this.data.isThreadMuted 68 } 69 70 get moderation(): PostModeration { 71 return this.data.moderation 72 } 73 74 assignTreeModels( 75 v: AppBskyFeedDefs.ThreadViewPost, 76 highlightedPostUri: string, 77 includeParent = true, 78 includeChildren = true, 79 ) { 80 // parents 81 if (includeParent && v.parent) { 82 if (AppBskyFeedDefs.isThreadViewPost(v.parent)) { 83 const parentModel = new PostThreadItemModel(this.rootStore, v.parent) 84 parentModel._depth = this._depth - 1 85 parentModel._showChildReplyLine = true 86 if (v.parent.parent) { 87 parentModel._showParentReplyLine = true 88 parentModel.assignTreeModels( 89 v.parent, 90 highlightedPostUri, 91 true, 92 false, 93 ) 94 } 95 this.parent = parentModel 96 } else if (AppBskyFeedDefs.isNotFoundPost(v.parent)) { 97 this.parent = v.parent 98 } else if (AppBskyFeedDefs.isBlockedPost(v.parent)) { 99 this.parent = v.parent 100 } 101 } 102 // replies 103 if (includeChildren && v.replies) { 104 const replies = [] 105 for (const item of v.replies) { 106 if (AppBskyFeedDefs.isThreadViewPost(item)) { 107 const itemModel = new PostThreadItemModel(this.rootStore, item) 108 itemModel._depth = this._depth + 1 109 itemModel._showParentReplyLine = 110 itemModel.parentUri !== highlightedPostUri 111 if (item.replies?.length) { 112 itemModel._showChildReplyLine = true 113 itemModel.assignTreeModels(item, highlightedPostUri, false, true) 114 } 115 replies.push(itemModel) 116 } else if (AppBskyFeedDefs.isNotFoundPost(item)) { 117 replies.push(item) 118 } 119 } 120 this.replies = replies 121 } 122 } 123 124 async toggleLike() { 125 this.data.toggleLike() 126 } 127 128 async toggleRepost() { 129 this.data.toggleRepost() 130 } 131 132 async toggleThreadMute() { 133 this.data.toggleThreadMute() 134 } 135 136 async delete() { 137 this.data.delete() 138 } 139}