WIP additional thread participants
This commit is contained in:
@@ -41,6 +41,8 @@ export class FeedViewPostsSlice {
|
|||||||
isFallbackMarker: boolean
|
isFallbackMarker: boolean
|
||||||
isOrphan: boolean
|
isOrphan: boolean
|
||||||
rootUri: string
|
rootUri: string
|
||||||
|
participantDids: Set<string> = new Set()
|
||||||
|
additionalParticipantProfiles: AppBskyActorDefs.ProfileViewBasic[] = []
|
||||||
|
|
||||||
constructor(feedPost: FeedViewPost) {
|
constructor(feedPost: FeedViewPost) {
|
||||||
const {post, reply, reason} = feedPost
|
const {post, reply, reason} = feedPost
|
||||||
@@ -211,12 +213,19 @@ export class FeedViewPostsSlice {
|
|||||||
rootAuthor,
|
rootAuthor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAuthorDids(): string[] {
|
||||||
|
return Object.values(this.getAuthors())
|
||||||
|
.map(p => (p ? p.did : undefined))
|
||||||
|
.filter(Boolean) as string[]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FeedTuner {
|
export class FeedTuner {
|
||||||
seenKeys: Set<string> = new Set()
|
seenKeys: Set<string> = new Set()
|
||||||
seenUris: Set<string> = new Set()
|
seenUris: Set<string> = new Set()
|
||||||
seenRootUris: Set<string> = new Set()
|
seenRootUris: Map<string, {participantDids: Set<string>}> = new Map()
|
||||||
|
profileMap: Map<string, AppBskyActorDefs.ProfileViewBasic> = new Map()
|
||||||
|
|
||||||
constructor(public tunerFns: FeedTunerFn[]) {}
|
constructor(public tunerFns: FeedTunerFn[]) {}
|
||||||
|
|
||||||
@@ -345,13 +354,36 @@ export class FeedTuner {
|
|||||||
dryRun: boolean,
|
dryRun: boolean,
|
||||||
): FeedViewPostsSlice[] {
|
): FeedViewPostsSlice[] {
|
||||||
for (let i = 0; i < slices.length; i++) {
|
for (let i = 0; i < slices.length; i++) {
|
||||||
const rootUri = slices[i].rootUri
|
const slice = slices[i]
|
||||||
if (!slices[i].isRepost && tuner.seenRootUris.has(rootUri)) {
|
const rootUri = slice.rootUri
|
||||||
|
const authorsDids = slice.getAuthorDids()
|
||||||
|
if (!slice.isRepost && tuner.seenRootUris.has(rootUri)) {
|
||||||
|
const seen = tuner.seenRootUris.get(rootUri)!
|
||||||
|
for (const did of authorsDids) {
|
||||||
|
seen.participantDids.add(did)
|
||||||
|
}
|
||||||
slices.splice(i, 1)
|
slices.splice(i, 1)
|
||||||
i--
|
i--
|
||||||
} else {
|
} else {
|
||||||
if (!dryRun) {
|
if (!dryRun) {
|
||||||
tuner.seenRootUris.add(rootUri)
|
const participantDids = new Set(authorsDids)
|
||||||
|
slice.participantDids = participantDids
|
||||||
|
tuner.seenRootUris.set(rootUri, {participantDids})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const profile of Object.values(slice.getAuthors())) {
|
||||||
|
if (profile) {
|
||||||
|
tuner.profileMap.set(profile.did, profile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const slice of slices) {
|
||||||
|
const visibleAuthors = new Set(slice.getAuthorDids())
|
||||||
|
for (const userDid of slice.participantDids) {
|
||||||
|
if (visibleAuthors.has(userDid)) continue
|
||||||
|
const profile = tuner.profileMap.get(userDid)
|
||||||
|
if (profile) {
|
||||||
|
slice.additionalParticipantProfiles.push(profile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ export interface FeedPostSlice {
|
|||||||
| AppBskyFeedDefs.ReasonRepost
|
| AppBskyFeedDefs.ReasonRepost
|
||||||
| ReasonFeedSource
|
| ReasonFeedSource
|
||||||
| {[k: string]: unknown; $type: string}
|
| {[k: string]: unknown; $type: string}
|
||||||
|
additionalParticipantProfiles?: AppBskyActorDefs.ProfileViewBasic[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FeedPageUnselected {
|
export interface FeedPageUnselected {
|
||||||
@@ -318,6 +319,8 @@ export function usePostFeedQuery(
|
|||||||
isFallbackMarker: slice.isFallbackMarker,
|
isFallbackMarker: slice.isFallbackMarker,
|
||||||
feedContext: slice.feedContext,
|
feedContext: slice.feedContext,
|
||||||
reason: slice.reason,
|
reason: slice.reason,
|
||||||
|
additionalParticipantProfiles:
|
||||||
|
slice.additionalParticipantProfiles,
|
||||||
items: slice.items.map((item, i) => {
|
items: slice.items.map((item, i) => {
|
||||||
const feedPostSliceItem: FeedPostSliceItem = {
|
const feedPostSliceItem: FeedPostSliceItem = {
|
||||||
_reactKey: `${slice._reactKey}-${i}-${item.post.uri}`,
|
_reactKey: `${slice._reactKey}-${i}-${item.post.uri}`,
|
||||||
|
|||||||
@@ -84,9 +84,11 @@ export function FeedItem({
|
|||||||
isParentBlocked,
|
isParentBlocked,
|
||||||
isParentNotFound,
|
isParentNotFound,
|
||||||
rootPost,
|
rootPost,
|
||||||
|
additionalParticipantProfiles,
|
||||||
}: FeedItemProps & {
|
}: FeedItemProps & {
|
||||||
post: AppBskyFeedDefs.PostView
|
post: AppBskyFeedDefs.PostView
|
||||||
rootPost: AppBskyFeedDefs.PostView
|
rootPost: AppBskyFeedDefs.PostView
|
||||||
|
additionalParticipantProfiles?: AppBskyActorDefs.ProfileViewBasic[]
|
||||||
}): React.ReactNode {
|
}): React.ReactNode {
|
||||||
const postShadowed = usePostShadow(post)
|
const postShadowed = usePostShadow(post)
|
||||||
const richText = useMemo(
|
const richText = useMemo(
|
||||||
@@ -120,6 +122,7 @@ export function FeedItem({
|
|||||||
isParentBlocked={isParentBlocked}
|
isParentBlocked={isParentBlocked}
|
||||||
isParentNotFound={isParentNotFound}
|
isParentNotFound={isParentNotFound}
|
||||||
rootPost={rootPost}
|
rootPost={rootPost}
|
||||||
|
additionalParticipantProfiles={additionalParticipantProfiles}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -142,10 +145,12 @@ let FeedItemInner = ({
|
|||||||
isParentBlocked,
|
isParentBlocked,
|
||||||
isParentNotFound,
|
isParentNotFound,
|
||||||
rootPost,
|
rootPost,
|
||||||
|
additionalParticipantProfiles,
|
||||||
}: FeedItemProps & {
|
}: FeedItemProps & {
|
||||||
richText: RichTextAPI
|
richText: RichTextAPI
|
||||||
post: Shadow<AppBskyFeedDefs.PostView>
|
post: Shadow<AppBskyFeedDefs.PostView>
|
||||||
rootPost: AppBskyFeedDefs.PostView
|
rootPost: AppBskyFeedDefs.PostView
|
||||||
|
additionalParticipantProfiles?: AppBskyActorDefs.ProfileViewBasic[]
|
||||||
}): React.ReactNode => {
|
}): React.ReactNode => {
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const {openComposer} = useComposerControls()
|
const {openComposer} = useComposerControls()
|
||||||
@@ -392,6 +397,16 @@ let FeedItemInner = ({
|
|||||||
feedContext={feedContext}
|
feedContext={feedContext}
|
||||||
threadgateRecord={threadgateRecord}
|
threadgateRecord={threadgateRecord}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{additionalParticipantProfiles?.length && (
|
||||||
|
<View>
|
||||||
|
<Text>
|
||||||
|
{additionalParticipantProfiles
|
||||||
|
.map(p => p.displayName)
|
||||||
|
.join(', ')}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ let FeedSlice = ({
|
|||||||
isParentBlocked={slice.items[0].isParentBlocked}
|
isParentBlocked={slice.items[0].isParentBlocked}
|
||||||
isParentNotFound={slice.items[0].isParentNotFound}
|
isParentNotFound={slice.items[0].isParentNotFound}
|
||||||
rootPost={slice.items[0].post}
|
rootPost={slice.items[0].post}
|
||||||
|
additionalParticipantProfiles={slice.additionalParticipantProfiles}
|
||||||
/>
|
/>
|
||||||
<ViewFullThread uri={slice.items[0].uri} />
|
<ViewFullThread uri={slice.items[0].uri} />
|
||||||
<FeedItem
|
<FeedItem
|
||||||
@@ -99,6 +100,9 @@ let FeedSlice = ({
|
|||||||
isParentNotFound={slice.items[i].isParentNotFound}
|
isParentNotFound={slice.items[i].isParentNotFound}
|
||||||
hideTopBorder={hideTopBorder && i === 0}
|
hideTopBorder={hideTopBorder && i === 0}
|
||||||
rootPost={slice.items[0].post}
|
rootPost={slice.items[0].post}
|
||||||
|
additionalParticipantProfiles={
|
||||||
|
i === 0 ? slice.additionalParticipantProfiles : undefined
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user