Skip to content

Commit ebeb247

Browse files
committed
feat: topic replay list
1 parent 7849a84 commit ebeb247

File tree

2 files changed

+105
-1
lines changed

2 files changed

+105
-1
lines changed

src/i18n/locales/zh.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@
151151
"message": "写点啥...",
152152
"empty": "无内容。",
153153
"noResult": "无内容。 ",
154-
"noFound": "未找到无内容",
154+
"noFound": "未找到内容",
155155
"noTopics": "还没有任何主题.",
156156
"noReplies": "还没有任何回复.",
157157
"noNodes": "还没有任何节点.",
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/**
2+
* Created by leon<[email protected]> on 22/04/28.
3+
*/
4+
import { Placeholder, Spinner, useToast } from '@src/components'
5+
import { translate } from '@src/i18n'
6+
import { ITheme, SylCommon, useTheme } from '@src/theme'
7+
import { V2exObject } from '@src/types'
8+
import { v2exLib } from '@src/v2ex'
9+
import React, { useCallback, useEffect, useState } from 'react'
10+
import { FlatList, RefreshControl, StyleProp, View, ViewStyle } from 'react-native'
11+
import TopicReplayItem from './TopicReplayItem'
12+
13+
/**
14+
* TopicReplayList props
15+
*/
16+
export interface TopicReplayListProps {
17+
containerStyle?: StyleProp<ViewStyle>
18+
19+
topicId: number
20+
}
21+
22+
const TopicReplayList: React.FC<TopicReplayListProps> = ({ containerStyle, topicId }: TopicReplayListProps) => {
23+
const { theme } = useTheme()
24+
const { showMessage } = useToast()
25+
const [refreshing, setRefreshing] = useState<boolean>(false)
26+
const [list, setList] = useState<V2exObject.TopicReply[] | undefined>(undefined)
27+
28+
const fetchReplay = useCallback(() => {
29+
v2exLib.reply.replies(topicId).then(
30+
(res) => {
31+
setList(res)
32+
setRefreshing(false)
33+
},
34+
(err) => {
35+
showMessage(translate('error.network'))
36+
setRefreshing(false)
37+
}
38+
)
39+
}, [topicId, v2exLib])
40+
41+
useEffect(() => {
42+
onRefresh()
43+
}, [])
44+
45+
const onRefresh = () => {
46+
setRefreshing(true)
47+
setList(undefined)
48+
fetchReplay()
49+
}
50+
51+
const renderItemRow = ({ item }: { item: V2exObject.TopicReply }) =>
52+
!item || item === null ? null : <TopicReplayItem containerStyle={styles.itemContainer(theme)} info={item} />
53+
54+
const renderItemSeparator = () => <View style={styles.itemSeparator(theme)} />
55+
56+
const renderContent = () => {
57+
if (!list) {
58+
return <Spinner style={{ marginTop: 50 }} />
59+
}
60+
61+
if (list.length > 0) {
62+
return (
63+
<FlatList
64+
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />}
65+
data={list}
66+
renderItem={renderItemRow}
67+
keyExtractor={(item, index) => index.toString()}
68+
numColumns={1}
69+
horizontal={false}
70+
key={'ONE COLUMN'}
71+
maxToRenderPerBatch={10}
72+
initialNumToRender={10}
73+
ItemSeparatorComponent={renderItemSeparator}
74+
/>
75+
)
76+
}
77+
return (
78+
<Placeholder
79+
placeholderText={translate('placeholder.noResult')}
80+
buttonText={translate('button.tryAgain')}
81+
buttonPress={onRefresh}
82+
/>
83+
)
84+
}
85+
86+
return <View style={[styles.container(theme), containerStyle]}>{renderContent()}</View>
87+
}
88+
89+
/**
90+
* @description styles settings
91+
*/
92+
const styles = {
93+
container: (theme: ITheme): ViewStyle => ({
94+
flex: 1
95+
}),
96+
itemContainer: (theme: ITheme): ViewStyle => ({
97+
...SylCommon.Card.container(theme)
98+
}),
99+
itemSeparator: (theme: ITheme) => ({
100+
height: 0
101+
})
102+
}
103+
104+
export default TopicReplayList

0 commit comments

Comments
 (0)