|
@@ -70,12 +70,15 @@ export const RecordModal = forwardRef<RecordModalRef, RecordModalProps>(({ poolI
|
|
|
const currentLastId = isRefresh ? undefined : lastId;
|
|
const currentLastId = isRefresh ? undefined : lastId;
|
|
|
const res = await getBuyRecord(poolId, currentLastId, activeTab.value as any);
|
|
const res = await getBuyRecord(poolId, currentLastId, activeTab.value as any);
|
|
|
if (res && res.length > 0) {
|
|
if (res && res.length > 0) {
|
|
|
- setData(prev => isRefresh ? res : [...prev, ...res]);
|
|
|
|
|
|
|
+ setData(prev => {
|
|
|
|
|
+ if (isRefresh) return res;
|
|
|
|
|
+ // Deduplicate based on ID
|
|
|
|
|
+ const existingIds = new Set(prev.map(item => item.id));
|
|
|
|
|
+ const newItems = res.filter(item => !existingIds.has(item.id));
|
|
|
|
|
+ return [...prev, ...newItems];
|
|
|
|
|
+ });
|
|
|
setLastId(res[res.length - 1].id);
|
|
setLastId(res[res.length - 1].id);
|
|
|
- // Assuming page size is 10 or 20. If less than that, no more data.
|
|
|
|
|
- // Let's assume default is 10. If strictly < 10, definitely no more.
|
|
|
|
|
- // If == 10, maybe more.
|
|
|
|
|
- // Safer: if 0 returned, handled by outside if.
|
|
|
|
|
|
|
+ // Assuming page size is 10 or 20.
|
|
|
} else {
|
|
} else {
|
|
|
setHasMore(false);
|
|
setHasMore(false);
|
|
|
}
|
|
}
|
|
@@ -95,12 +98,6 @@ export const RecordModal = forwardRef<RecordModalRef, RecordModalProps>(({ poolI
|
|
|
setLastId(undefined);
|
|
setLastId(undefined);
|
|
|
setData([]);
|
|
setData([]);
|
|
|
setHasMore(true);
|
|
setHasMore(true);
|
|
|
- // We can't immediately call loadData due to state update async nature,
|
|
|
|
|
- // but let's assume useEffect or immediate call with arg works.
|
|
|
|
|
- // Actually best to useEffect on activeTab change?
|
|
|
|
|
- // Or specific effect for tab
|
|
|
|
|
- // Let's do explicit reload in effect or here
|
|
|
|
|
- // setData is sync-ish in RN usually batching, let's use effect.
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
@@ -117,10 +114,7 @@ export const RecordModal = forwardRef<RecordModalRef, RecordModalProps>(({ poolI
|
|
|
<Image source={{ uri: item.avatar || Images.common.defaultAvatar }} style={styles.avatar} />
|
|
<Image source={{ uri: item.avatar || Images.common.defaultAvatar }} style={styles.avatar} />
|
|
|
<Text style={styles.nickname} numberOfLines={1}>{item.nickname}</Text>
|
|
<Text style={styles.nickname} numberOfLines={1}>{item.nickname}</Text>
|
|
|
|
|
|
|
|
- {/* Level Icon - Assuming we have images for level text similar to legacy */}
|
|
|
|
|
- {/* Legacy: :src="LEVEL_MAP[item.level].titleText" */}
|
|
|
|
|
- {/* We don't have titleText in our config yet, need to map or use text */}
|
|
|
|
|
- {/* For now use Text with color */}
|
|
|
|
|
|
|
+ {/* Level Icon */}
|
|
|
<View style={[styles.levelTag, { borderColor: LEVEL_MAP[item.level]?.color || '#000' }]}>
|
|
<View style={[styles.levelTag, { borderColor: LEVEL_MAP[item.level]?.color || '#000' }]}>
|
|
|
<Text style={[styles.levelText, { color: LEVEL_MAP[item.level]?.color || '#000' }]}>
|
|
<Text style={[styles.levelText, { color: LEVEL_MAP[item.level]?.color || '#000' }]}>
|
|
|
{LEVEL_MAP[item.level]?.title}
|
|
{LEVEL_MAP[item.level]?.title}
|
|
@@ -160,12 +154,12 @@ export const RecordModal = forwardRef<RecordModalRef, RecordModalProps>(({ poolI
|
|
|
<View style={styles.statItem}>
|
|
<View style={styles.statItem}>
|
|
|
<Text style={styles.statNum}>{taggingA}</Text>
|
|
<Text style={styles.statNum}>{taggingA}</Text>
|
|
|
<Text style={styles.statLabel}>发未出</Text>
|
|
<Text style={styles.statLabel}>发未出</Text>
|
|
|
- <Text style={[styles.statLevel, { color: LEVEL_MAP.A.color }]}>超神款</Text>
|
|
|
|
|
|
|
+ <Image source={{ uri: LEVEL_MAP.A.titleText }} style={{ width: 45, height: 16 }} contentFit="contain" />
|
|
|
</View>
|
|
</View>
|
|
|
<View style={styles.statItem}>
|
|
<View style={styles.statItem}>
|
|
|
<Text style={styles.statNum}>{taggingB}</Text>
|
|
<Text style={styles.statNum}>{taggingB}</Text>
|
|
|
<Text style={styles.statLabel}>发未出</Text>
|
|
<Text style={styles.statLabel}>发未出</Text>
|
|
|
- <Text style={[styles.statLevel, { color: LEVEL_MAP.B.color }]}>欧皇款</Text>
|
|
|
|
|
|
|
+ <Image source={{ uri: LEVEL_MAP.B.titleText }} style={{ width: 45, height: 16 }} contentFit="contain" />
|
|
|
</View>
|
|
</View>
|
|
|
</ImageBackground>
|
|
</ImageBackground>
|
|
|
|
|
|
|
@@ -188,7 +182,7 @@ export const RecordModal = forwardRef<RecordModalRef, RecordModalProps>(({ poolI
|
|
|
<FlatList
|
|
<FlatList
|
|
|
data={data}
|
|
data={data}
|
|
|
renderItem={renderItem}
|
|
renderItem={renderItem}
|
|
|
- keyExtractor={(item, index) => item.id || String(index)}
|
|
|
|
|
|
|
+ keyExtractor={(item, index) => (item.id ? `${item.id}_${index}` : String(index))}
|
|
|
style={styles.list}
|
|
style={styles.list}
|
|
|
contentContainerStyle={{ paddingBottom: 20 }}
|
|
contentContainerStyle={{ paddingBottom: 20 }}
|
|
|
onEndReached={() => loadData(false)}
|
|
onEndReached={() => loadData(false)}
|
|
@@ -257,17 +251,17 @@ const styles = StyleSheet.create({
|
|
|
alignItems: 'center',
|
|
alignItems: 'center',
|
|
|
},
|
|
},
|
|
|
statNum: {
|
|
statNum: {
|
|
|
- fontSize: 16,
|
|
|
|
|
- fontWeight: 'bold',
|
|
|
|
|
- color: '#fff',
|
|
|
|
|
- textShadowColor: '#000',
|
|
|
|
|
- textShadowOffset: { width: -1, height: -1 },
|
|
|
|
|
|
|
+ fontSize: 24,
|
|
|
|
|
+ fontWeight: '900',
|
|
|
|
|
+ color: '#000',
|
|
|
|
|
+ textShadowColor: '#fff',
|
|
|
|
|
+ textShadowOffset: { width: 1, height: 1 },
|
|
|
textShadowRadius: 1,
|
|
textShadowRadius: 1,
|
|
|
},
|
|
},
|
|
|
statLabel: {
|
|
statLabel: {
|
|
|
fontSize: 12,
|
|
fontSize: 12,
|
|
|
color: '#928D81',
|
|
color: '#928D81',
|
|
|
- fontWeight: '300',
|
|
|
|
|
|
|
+ fontWeight: '300',
|
|
|
marginHorizontal: 8
|
|
marginHorizontal: 8
|
|
|
},
|
|
},
|
|
|
statLevel: { fontSize: 12, fontWeight: 'bold' },
|
|
statLevel: { fontSize: 12, fontWeight: 'bold' },
|