Improve thread rendering (show reply lines)

zio/stable
Paul Frazee 2022-09-28 15:03:16 -05:00
parent 9f91edc1d1
commit a21a0d2988
4 changed files with 77 additions and 6 deletions

View File

@ -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)
}

View File

@ -88,7 +88,6 @@ export class SessionModel {
}
clear() {
console.log('clear()')
this.data = null
}

View File

@ -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',
},

View File

@ -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,