Elide long threads in the feed (close #333)
This commit is contained in:
parent
b692f29773
commit
1e34e62259
3 changed files with 85 additions and 38 deletions
|
@ -200,6 +200,7 @@ export class FeedSliceModel {
|
||||||
get isThread() {
|
get isThread() {
|
||||||
return (
|
return (
|
||||||
this.items.length > 1 &&
|
this.items.length > 1 &&
|
||||||
|
!this.items[0].reply &&
|
||||||
this.items.every(
|
this.items.every(
|
||||||
item => item.post.author.did === this.items[0].post.author.did,
|
item => item.post.author.did === this.items[0].post.author.did,
|
||||||
)
|
)
|
||||||
|
@ -207,7 +208,7 @@ export class FeedSliceModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
get isReply() {
|
get isReply() {
|
||||||
return this.items.length === 2 && !this.isThread
|
return this.items.length > 1 && !this.isThread
|
||||||
}
|
}
|
||||||
|
|
||||||
get rootItem() {
|
get rootItem() {
|
||||||
|
|
|
@ -2,7 +2,6 @@ import React, {useMemo, useState} from 'react'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {Linking, StyleSheet, View} from 'react-native'
|
import {Linking, StyleSheet, View} from 'react-native'
|
||||||
import Clipboard from '@react-native-clipboard/clipboard'
|
import Clipboard from '@react-native-clipboard/clipboard'
|
||||||
import Svg, {Circle, Line} from 'react-native-svg'
|
|
||||||
import {AtUri} from '../../../third-party/uri'
|
import {AtUri} from '../../../third-party/uri'
|
||||||
import {
|
import {
|
||||||
FontAwesomeIcon,
|
FontAwesomeIcon,
|
||||||
|
@ -253,32 +252,6 @@ export const FeedItem = observer(function ({
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</Link>
|
</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>
|
</PostMutedWrapper>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -348,14 +321,4 @@ const styles = StyleSheet.create({
|
||||||
ctrls: {
|
ctrls: {
|
||||||
marginTop: 4,
|
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 React from 'react'
|
||||||
|
import {StyleSheet, View} from 'react-native'
|
||||||
import {FeedSliceModel} from 'state/models/feed-view'
|
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 {FeedItem} from './FeedItem'
|
||||||
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
|
||||||
export function FeedSlice({
|
export function FeedSlice({
|
||||||
slice,
|
slice,
|
||||||
|
@ -11,6 +17,39 @@ export function FeedSlice({
|
||||||
showFollowBtn?: boolean
|
showFollowBtn?: boolean
|
||||||
ignoreMuteFor?: string
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
{slice.items.map((item, i) => (
|
{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…
Add table
Add a link
Reference in a new issue