Add replying-to context to threads

zio/stable
Paul Frazee 2022-11-23 14:22:40 -06:00
parent a993499890
commit 2b37b6549b
2 changed files with 73 additions and 18 deletions

View File

@ -12,6 +12,17 @@ function* reactKeyGenerator(): Generator<string> {
}
}
interface ReplyingTo {
author: {
handle: string
displayName?: string
}
text: string
}
interface OriginalRecord {
text: string
}
export class PostThreadViewPostMyStateModel {
repost?: string
upvote?: string
@ -52,7 +63,7 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
myState = new PostThreadViewPostMyStateModel()
// added data
replyingToAuthor?: string
replyingTo?: ReplyingTo
constructor(
public rootStore: RootStoreModel,
@ -74,6 +85,7 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
v: GetPostThread.Post,
includeParent = true,
includeChildren = true,
isFirstChild = true,
) {
// parents
if (includeParent && v.parent) {
@ -89,12 +101,19 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
}
this.parent = parentModel
}
if (v.parent?.author.handle) {
this.replyingToAuthor = v.parent.author.handle
if (!includeParent && v.parent?.author.handle && !isFirstChild) {
this.replyingTo = {
author: {
handle: v.parent.author.handle,
displayName: v.parent.author.displayName,
},
text: (v.parent.record as OriginalRecord).text,
}
}
// replies
if (includeChildren && v.replies) {
const replies = []
let isChildFirstChild = true
for (const item of v.replies) {
// TODO: validate .record
const itemModel = new PostThreadViewPostModel(
@ -104,8 +123,15 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
)
itemModel._depth = this._depth + 1
if (item.replies) {
itemModel.assignTreeModels(keyGen, item, false, true)
itemModel.assignTreeModels(
keyGen,
item,
false,
true,
isChildFirstChild,
)
}
isChildFirstChild = false
replies.push(itemModel)
}
this.replies = replies

View File

@ -17,6 +17,7 @@ import {PostMeta} from '../util/PostMeta'
import {PostCtrls} from '../util/PostCtrls'
const PARENT_REPLY_LINE_LENGTH = 8
const REPLYING_TO_LINE_LENGTH = 6
export const PostThreadItem = observer(function PostThreadItem({
item,
@ -204,8 +205,25 @@ export const PostThreadItem = observer(function PostThreadItem({
} else {
return (
<Link style={styles.outer} href={itemHref} title={itemTitle}>
{!!item.replyingToAuthor && <View style={styles.parentReplyLine} />}
{!item.replyingTo && item.record.reply && (
<View style={styles.parentReplyLine} />
)}
{item.replies?.length !== 0 && <View style={styles.childReplyLine} />}
{item.replyingTo ? (
<View style={styles.replyingTo}>
<View style={styles.replyingToLine} />
<View style={styles.replyingToAvatar}>
<UserAvatar
handle={item.replyingTo.author.handle}
displayName={item.replyingTo.author.displayName}
size={30}
/>
</View>
<Text style={styles.replyingToText} numberOfLines={2}>
{item.replyingTo.text}
</Text>
</View>
) : undefined}
<View style={styles.layout}>
<View style={styles.layoutAvi}>
<Link href={authorHref} title={authorTitle}>
@ -227,19 +245,6 @@ export const PostThreadItem = observer(function PostThreadItem({
isAuthor={item.author.did === store.me.did}
onDeletePost={onDeletePost}
/>
{item.replyingToAuthor &&
item.replyingToAuthor !== item.author.handle && (
<View style={[s.flexRow, s.mb5, {alignItems: 'center'}]}>
<Text style={[s.gray5, s.f15, s.mr2]}>Replying to</Text>
<Link
href={`/profile/${item.replyingToAuthor}`}
title={`@${item.replyingToAuthor}`}>
<Text style={[s.f14, s.blue3]}>
@{item.replyingToAuthor}
</Text>
</Link>
</View>
)}
<View style={styles.postTextContainer}>
<RichText
text={record.text}
@ -287,6 +292,30 @@ const styles = StyleSheet.create({
borderLeftWidth: 2,
borderLeftColor: colors.gray2,
},
replyingToLine: {
position: 'absolute',
left: 34,
bottom: -1 * REPLYING_TO_LINE_LENGTH,
height: REPLYING_TO_LINE_LENGTH,
borderLeftWidth: 2,
borderLeftColor: colors.gray2,
},
replyingTo: {
flexDirection: 'row',
backgroundColor: colors.white,
paddingLeft: 8,
paddingTop: 12,
paddingBottom: 0,
paddingRight: 24,
},
replyingToAvatar: {
marginLeft: 12,
marginRight: 20,
},
replyingToText: {
flex: 1,
color: colors.gray5,
},
layout: {
flexDirection: 'row',
},