Improve thread rendering (show reply lines)
parent
9f91edc1d1
commit
a21a0d2988
|
@ -43,6 +43,9 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
|
|||
indexedAt: string = ''
|
||||
myState = new PostThreadViewPostMyStateModel()
|
||||
|
||||
// added data
|
||||
replyingToAuthor?: string
|
||||
|
||||
constructor(
|
||||
public rootStore: RootStoreModel,
|
||||
reactKey: string,
|
||||
|
@ -58,9 +61,14 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
|
|||
}
|
||||
}
|
||||
|
||||
assignTreeModels(keyGen: Generator<string>, v: GetPostThread.Post) {
|
||||
assignTreeModels(
|
||||
keyGen: Generator<string>,
|
||||
v: GetPostThread.Post,
|
||||
includeParent = true,
|
||||
includeChildren = true,
|
||||
) {
|
||||
// parents
|
||||
if (v.parent) {
|
||||
if (includeParent && v.parent) {
|
||||
// TODO: validate .record
|
||||
const parentModel = new PostThreadViewPostModel(
|
||||
this.rootStore,
|
||||
|
@ -69,12 +77,15 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
|
|||
)
|
||||
parentModel._depth = this._depth - 1
|
||||
if (v.parent.parent) {
|
||||
parentModel.assignTreeModels(keyGen, v.parent)
|
||||
parentModel.assignTreeModels(keyGen, v.parent, true, false)
|
||||
}
|
||||
this.parent = parentModel
|
||||
}
|
||||
if (v.parent?.author.name) {
|
||||
this.replyingToAuthor = v.parent.author.name
|
||||
}
|
||||
// replies
|
||||
if (v.replies) {
|
||||
if (includeChildren && v.replies) {
|
||||
const replies = []
|
||||
for (const item of v.replies) {
|
||||
// TODO: validate .record
|
||||
|
@ -85,7 +96,7 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
|
|||
)
|
||||
itemModel._depth = this._depth + 1
|
||||
if (item.replies) {
|
||||
itemModel.assignTreeModels(keyGen, item)
|
||||
itemModel.assignTreeModels(keyGen, item, false, true)
|
||||
}
|
||||
replies.push(itemModel)
|
||||
}
|
||||
|
|
|
@ -88,7 +88,6 @@ export class SessionModel {
|
|||
}
|
||||
|
||||
clear() {
|
||||
console.log('clear()')
|
||||
this.data = null
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React, {useMemo} from 'react'
|
||||
import {observer} from 'mobx-react-lite'
|
||||
import {Image, StyleSheet, Text, TouchableOpacity, View} from 'react-native'
|
||||
import Svg, {Line, Circle} from 'react-native-svg'
|
||||
import {AdxUri} from '../../../third-party/uri'
|
||||
import * as PostType from '../../../third-party/api/src/types/todo/social/post'
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
|
@ -13,6 +14,8 @@ import {ago, pluralize} from '../../lib/strings'
|
|||
import {DEF_AVATER} from '../../lib/assets'
|
||||
import {useStores} from '../../../state'
|
||||
|
||||
const PARENT_REPLY_LINE_LENGTH = 8
|
||||
|
||||
export const PostThreadItem = observer(function PostThreadItem({
|
||||
item,
|
||||
onPressShare,
|
||||
|
@ -185,11 +188,56 @@ export const PostThreadItem = observer(function PostThreadItem({
|
|||
} else {
|
||||
return (
|
||||
<Link style={styles.outer} href={itemHref} title={itemTitle}>
|
||||
{!!item.replyingToAuthor && (
|
||||
<View style={styles.parentReplyLine}>
|
||||
<Svg width="10" height={PARENT_REPLY_LINE_LENGTH}>
|
||||
<Line
|
||||
x1="5"
|
||||
x2="5"
|
||||
y1="0"
|
||||
y2={PARENT_REPLY_LINE_LENGTH}
|
||||
stroke={colors.gray2}
|
||||
strokeWidth={2}
|
||||
/>
|
||||
</Svg>
|
||||
</View>
|
||||
)}
|
||||
{item.replies?.length !== 0 && (
|
||||
<View style={styles.childReplyLine}>
|
||||
<Svg width="10" height={100}>
|
||||
<Line
|
||||
x1="5"
|
||||
x2="5"
|
||||
y1="0"
|
||||
y2={100}
|
||||
stroke={colors.gray2}
|
||||
strokeWidth={2}
|
||||
/>
|
||||
</Svg>
|
||||
</View>
|
||||
)}
|
||||
<View style={styles.layout}>
|
||||
<Link style={styles.layoutAvi} href={authorHref} title={authorTitle}>
|
||||
<Image style={styles.avi} source={DEF_AVATER} />
|
||||
</Link>
|
||||
<View style={styles.layoutContent}>
|
||||
{item.replyingToAuthor &&
|
||||
item.replyingToAuthor !== item.author.name && (
|
||||
<View style={[s.flexRow, {alignItems: 'center'}]}>
|
||||
<FontAwesomeIcon
|
||||
icon="reply"
|
||||
size={9}
|
||||
style={[s.gray4, s.mr5]}
|
||||
/>
|
||||
<Link
|
||||
href={`/profile/${item.replyingToAuthor}`}
|
||||
title={`@${item.replyingToAuthor}`}>
|
||||
<Text style={[s.f12, s.gray5]}>
|
||||
@{item.replyingToAuthor}
|
||||
</Text>
|
||||
</Link>
|
||||
</View>
|
||||
)}
|
||||
<View style={styles.meta}>
|
||||
<Link
|
||||
style={styles.metaItem}
|
||||
|
@ -236,6 +284,17 @@ const styles = StyleSheet.create({
|
|||
margin: 2,
|
||||
marginBottom: 0,
|
||||
},
|
||||
parentReplyLine: {
|
||||
position: 'absolute',
|
||||
left: 30,
|
||||
top: -1 * PARENT_REPLY_LINE_LENGTH + 6,
|
||||
},
|
||||
childReplyLine: {
|
||||
position: 'absolute',
|
||||
left: 30,
|
||||
top: 65,
|
||||
bottom: 0,
|
||||
},
|
||||
layout: {
|
||||
flexDirection: 'row',
|
||||
},
|
||||
|
|
|
@ -34,6 +34,7 @@ import {faPlus} from '@fortawesome/free-solid-svg-icons/faPlus'
|
|||
import {faShare} from '@fortawesome/free-solid-svg-icons/faShare'
|
||||
import {faShareFromSquare} from '@fortawesome/free-solid-svg-icons/faShareFromSquare'
|
||||
import {faShield} from '@fortawesome/free-solid-svg-icons/faShield'
|
||||
import {faReply} from '@fortawesome/free-solid-svg-icons/faReply'
|
||||
import {faRetweet} from '@fortawesome/free-solid-svg-icons/faRetweet'
|
||||
import {faUser} from '@fortawesome/free-regular-svg-icons/faUser'
|
||||
import {faUsers} from '@fortawesome/free-solid-svg-icons/faUsers'
|
||||
|
@ -73,6 +74,7 @@ export function setup() {
|
|||
faMessage,
|
||||
faPenNib,
|
||||
faPlus,
|
||||
faReply,
|
||||
faRetweet,
|
||||
faShare,
|
||||
faShareFromSquare,
|
||||
|
|
Loading…
Reference in New Issue