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