Elide long threads in the feed (close #333)
parent
b692f29773
commit
1e34e62259
|
@ -200,6 +200,7 @@ export class FeedSliceModel {
|
|||
get isThread() {
|
||||
return (
|
||||
this.items.length > 1 &&
|
||||
!this.items[0].reply &&
|
||||
this.items.every(
|
||||
item => item.post.author.did === this.items[0].post.author.did,
|
||||
)
|
||||
|
@ -207,7 +208,7 @@ export class FeedSliceModel {
|
|||
}
|
||||
|
||||
get isReply() {
|
||||
return this.items.length === 2 && !this.isThread
|
||||
return this.items.length > 1 && !this.isThread
|
||||
}
|
||||
|
||||
get rootItem() {
|
||||
|
|
|
@ -2,7 +2,6 @@ import React, {useMemo, useState} from 'react'
|
|||
import {observer} from 'mobx-react-lite'
|
||||
import {Linking, StyleSheet, View} from 'react-native'
|
||||
import Clipboard from '@react-native-clipboard/clipboard'
|
||||
import Svg, {Circle, Line} from 'react-native-svg'
|
||||
import {AtUri} from '../../../third-party/uri'
|
||||
import {
|
||||
FontAwesomeIcon,
|
||||
|
@ -253,32 +252,6 @@ export const FeedItem = observer(function ({
|
|||
</View>
|
||||
</View>
|
||||
</Link>
|
||||
{false /*isThreadChildElided*/ ? (
|
||||
<Link
|
||||
style={[pal.view, styles.viewFullThread]}
|
||||
href={itemHref}
|
||||
title={itemTitle}
|
||||
noFeedback>
|
||||
<View style={styles.viewFullThreadDots}>
|
||||
<Svg width="4" height="30">
|
||||
<Line
|
||||
x1="2"
|
||||
y1="0"
|
||||
x2="2"
|
||||
y2="8"
|
||||
stroke={pal.colors.replyLine}
|
||||
strokeWidth="2"
|
||||
/>
|
||||
<Circle x="2" y="14" r="1.5" fill={pal.colors.replyLineDot} />
|
||||
<Circle x="2" y="20" r="1.5" fill={pal.colors.replyLineDot} />
|
||||
<Circle x="2" y="26" r="1.5" fill={pal.colors.replyLineDot} />
|
||||
</Svg>
|
||||
</View>
|
||||
<Text type="md" style={pal.link}>
|
||||
View full thread
|
||||
</Text>
|
||||
</Link>
|
||||
) : undefined}
|
||||
</PostMutedWrapper>
|
||||
)
|
||||
})
|
||||
|
@ -348,14 +321,4 @@ const styles = StyleSheet.create({
|
|||
ctrls: {
|
||||
marginTop: 4,
|
||||
},
|
||||
viewFullThread: {
|
||||
paddingTop: 12,
|
||||
paddingBottom: 2,
|
||||
paddingLeft: 80,
|
||||
},
|
||||
viewFullThreadDots: {
|
||||
position: 'absolute',
|
||||
left: 41,
|
||||
top: 0,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
import React from 'react'
|
||||
import {StyleSheet, View} from 'react-native'
|
||||
import {FeedSliceModel} from 'state/models/feed-view'
|
||||
import {AtUri} from '../../../third-party/uri'
|
||||
import {Link} from '../util/Link'
|
||||
import {Text} from '../util/text/Text'
|
||||
import Svg, {Circle, Line} from 'react-native-svg'
|
||||
import {FeedItem} from './FeedItem'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
|
||||
export function FeedSlice({
|
||||
slice,
|
||||
|
@ -11,6 +17,39 @@ export function FeedSlice({
|
|||
showFollowBtn?: boolean
|
||||
ignoreMuteFor?: string
|
||||
}) {
|
||||
if (slice.isThread && slice.items.length > 3) {
|
||||
const last = slice.items.length - 1
|
||||
return (
|
||||
<>
|
||||
<FeedItem
|
||||
key={slice.items[0]._reactKey}
|
||||
item={slice.items[0]}
|
||||
isThreadParent={slice.isThreadParentAt(0)}
|
||||
isThreadChild={slice.isThreadChildAt(0)}
|
||||
showFollowBtn={showFollowBtn}
|
||||
ignoreMuteFor={ignoreMuteFor}
|
||||
/>
|
||||
<FeedItem
|
||||
key={slice.items[1]._reactKey}
|
||||
item={slice.items[1]}
|
||||
isThreadParent={slice.isThreadParentAt(1)}
|
||||
isThreadChild={slice.isThreadChildAt(1)}
|
||||
showFollowBtn={showFollowBtn}
|
||||
ignoreMuteFor={ignoreMuteFor}
|
||||
/>
|
||||
<ViewFullThread slice={slice} />
|
||||
<FeedItem
|
||||
key={slice.items[last]._reactKey}
|
||||
item={slice.items[last]}
|
||||
isThreadParent={slice.isThreadParentAt(last)}
|
||||
isThreadChild={slice.isThreadChildAt(last)}
|
||||
showFollowBtn={showFollowBtn}
|
||||
ignoreMuteFor={ignoreMuteFor}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{slice.items.map((item, i) => (
|
||||
|
@ -26,3 +65,47 @@ export function FeedSlice({
|
|||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function ViewFullThread({slice}: {slice: FeedSliceModel}) {
|
||||
const pal = usePalette('default')
|
||||
const itemHref = React.useMemo(() => {
|
||||
const urip = new AtUri(slice.rootItem.post.uri)
|
||||
return `/profile/${slice.rootItem.post.author.handle}/post/${urip.rkey}`
|
||||
}, [slice.rootItem.post.uri, slice.rootItem.post.author.handle])
|
||||
|
||||
return (
|
||||
<Link style={[pal.view, styles.viewFullThread]} href={itemHref} noFeedback>
|
||||
<View style={styles.viewFullThreadDots}>
|
||||
<Svg width="4" height="30">
|
||||
<Line
|
||||
x1="2"
|
||||
y1="0"
|
||||
x2="2"
|
||||
y2="8"
|
||||
stroke={pal.colors.replyLine}
|
||||
strokeWidth="2"
|
||||
/>
|
||||
<Circle x="2" y="16" r="1.5" fill={pal.colors.replyLineDot} />
|
||||
<Circle x="2" y="22" r="1.5" fill={pal.colors.replyLineDot} />
|
||||
<Circle x="2" y="28" r="1.5" fill={pal.colors.replyLineDot} />
|
||||
</Svg>
|
||||
</View>
|
||||
<Text type="md" style={pal.link}>
|
||||
View full thread
|
||||
</Text>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
viewFullThread: {
|
||||
paddingTop: 14,
|
||||
paddingBottom: 6,
|
||||
paddingLeft: 80,
|
||||
},
|
||||
viewFullThreadDots: {
|
||||
position: 'absolute',
|
||||
left: 41,
|
||||
top: 0,
|
||||
},
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue