Add replying-to context to threads
parent
a993499890
commit
2b37b6549b
|
@ -12,6 +12,17 @@ function* reactKeyGenerator(): Generator<string> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ReplyingTo {
|
||||||
|
author: {
|
||||||
|
handle: string
|
||||||
|
displayName?: string
|
||||||
|
}
|
||||||
|
text: string
|
||||||
|
}
|
||||||
|
interface OriginalRecord {
|
||||||
|
text: string
|
||||||
|
}
|
||||||
|
|
||||||
export class PostThreadViewPostMyStateModel {
|
export class PostThreadViewPostMyStateModel {
|
||||||
repost?: string
|
repost?: string
|
||||||
upvote?: string
|
upvote?: string
|
||||||
|
@ -52,7 +63,7 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
|
||||||
myState = new PostThreadViewPostMyStateModel()
|
myState = new PostThreadViewPostMyStateModel()
|
||||||
|
|
||||||
// added data
|
// added data
|
||||||
replyingToAuthor?: string
|
replyingTo?: ReplyingTo
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public rootStore: RootStoreModel,
|
public rootStore: RootStoreModel,
|
||||||
|
@ -74,6 +85,7 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
|
||||||
v: GetPostThread.Post,
|
v: GetPostThread.Post,
|
||||||
includeParent = true,
|
includeParent = true,
|
||||||
includeChildren = true,
|
includeChildren = true,
|
||||||
|
isFirstChild = true,
|
||||||
) {
|
) {
|
||||||
// parents
|
// parents
|
||||||
if (includeParent && v.parent) {
|
if (includeParent && v.parent) {
|
||||||
|
@ -89,12 +101,19 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
|
||||||
}
|
}
|
||||||
this.parent = parentModel
|
this.parent = parentModel
|
||||||
}
|
}
|
||||||
if (v.parent?.author.handle) {
|
if (!includeParent && v.parent?.author.handle && !isFirstChild) {
|
||||||
this.replyingToAuthor = v.parent.author.handle
|
this.replyingTo = {
|
||||||
|
author: {
|
||||||
|
handle: v.parent.author.handle,
|
||||||
|
displayName: v.parent.author.displayName,
|
||||||
|
},
|
||||||
|
text: (v.parent.record as OriginalRecord).text,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// replies
|
// replies
|
||||||
if (includeChildren && v.replies) {
|
if (includeChildren && v.replies) {
|
||||||
const replies = []
|
const replies = []
|
||||||
|
let isChildFirstChild = true
|
||||||
for (const item of v.replies) {
|
for (const item of v.replies) {
|
||||||
// TODO: validate .record
|
// TODO: validate .record
|
||||||
const itemModel = new PostThreadViewPostModel(
|
const itemModel = new PostThreadViewPostModel(
|
||||||
|
@ -104,8 +123,15 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
|
||||||
)
|
)
|
||||||
itemModel._depth = this._depth + 1
|
itemModel._depth = this._depth + 1
|
||||||
if (item.replies) {
|
if (item.replies) {
|
||||||
itemModel.assignTreeModels(keyGen, item, false, true)
|
itemModel.assignTreeModels(
|
||||||
|
keyGen,
|
||||||
|
item,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
isChildFirstChild,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
isChildFirstChild = false
|
||||||
replies.push(itemModel)
|
replies.push(itemModel)
|
||||||
}
|
}
|
||||||
this.replies = replies
|
this.replies = replies
|
||||||
|
|
|
@ -17,6 +17,7 @@ import {PostMeta} from '../util/PostMeta'
|
||||||
import {PostCtrls} from '../util/PostCtrls'
|
import {PostCtrls} from '../util/PostCtrls'
|
||||||
|
|
||||||
const PARENT_REPLY_LINE_LENGTH = 8
|
const PARENT_REPLY_LINE_LENGTH = 8
|
||||||
|
const REPLYING_TO_LINE_LENGTH = 6
|
||||||
|
|
||||||
export const PostThreadItem = observer(function PostThreadItem({
|
export const PostThreadItem = observer(function PostThreadItem({
|
||||||
item,
|
item,
|
||||||
|
@ -204,8 +205,25 @@ export const PostThreadItem = observer(function PostThreadItem({
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Link style={styles.outer} href={itemHref} title={itemTitle}>
|
<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.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.layout}>
|
||||||
<View style={styles.layoutAvi}>
|
<View style={styles.layoutAvi}>
|
||||||
<Link href={authorHref} title={authorTitle}>
|
<Link href={authorHref} title={authorTitle}>
|
||||||
|
@ -227,19 +245,6 @@ export const PostThreadItem = observer(function PostThreadItem({
|
||||||
isAuthor={item.author.did === store.me.did}
|
isAuthor={item.author.did === store.me.did}
|
||||||
onDeletePost={onDeletePost}
|
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}>
|
<View style={styles.postTextContainer}>
|
||||||
<RichText
|
<RichText
|
||||||
text={record.text}
|
text={record.text}
|
||||||
|
@ -287,6 +292,30 @@ const styles = StyleSheet.create({
|
||||||
borderLeftWidth: 2,
|
borderLeftWidth: 2,
|
||||||
borderLeftColor: colors.gray2,
|
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: {
|
layout: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue