fix(performer): tag chips → in-place horizontal filter selector
Follow-up to 1a4bf258 feedback (a627637b + 0264a3ff): the flexWrap chip list ate too much vertical space and tapping navigated away to TagScenes. Rework: single-row horizontal scroll of toggle-chips that filter the performer's scenes IN-PLACE (performer_ids + tags in one listScenes query, no navigation). Selected chip is highlighted with a ✕ affordance; tap again clears. One line tall instead of N rows. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
576a424615
commit
7f36865b5a
1 changed files with 38 additions and 20 deletions
|
|
@ -13,6 +13,7 @@ import {
|
||||||
Alert,
|
Alert,
|
||||||
FlatList,
|
FlatList,
|
||||||
Pressable,
|
Pressable,
|
||||||
|
ScrollView,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
Text,
|
Text,
|
||||||
View,
|
View,
|
||||||
|
|
@ -135,11 +136,16 @@ export function PerformerScenesScreen() {
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [navigation, name, isFavorite, addMutation.isPending, removeMutation.isPending]);
|
}, [navigation, name, isFavorite, addMutation.isPending, removeMutation.isPending]);
|
||||||
|
|
||||||
|
// Filtr tagu IN-PLACE (bug-report 0264a3ff: wybór tagu ma filtrować sceny tej
|
||||||
|
// aktorki w tym widoku, nie nawigować do osobnego ekranu). null = bez filtra.
|
||||||
|
const [selectedTag, setSelectedTag] = React.useState<{ slug: string; name: string } | null>(null);
|
||||||
|
|
||||||
const scenesQuery = useQuery({
|
const scenesQuery = useQuery({
|
||||||
queryKey: ['performer-scenes', id],
|
queryKey: ['performer-scenes', id, selectedTag?.slug ?? null],
|
||||||
queryFn: () =>
|
queryFn: () =>
|
||||||
client.listScenes({
|
client.listScenes({
|
||||||
performer_ids: [id],
|
performer_ids: [id],
|
||||||
|
tags: selectedTag ? [selectedTag.slug] : undefined,
|
||||||
sort: 'release_date',
|
sort: 'release_date',
|
||||||
per_page: 200,
|
per_page: 200,
|
||||||
// Sceny TPDB/StashDB bez tube-linków nie są usable — zawsze filtrujemy.
|
// Sceny TPDB/StashDB bez tube-linków nie są usable — zawsze filtrujemy.
|
||||||
|
|
@ -270,21 +276,31 @@ export function PerformerScenesScreen() {
|
||||||
</Pressable>
|
</Pressable>
|
||||||
</View>
|
</View>
|
||||||
{tab === 'scenes' && !!tagsQuery.data?.items.length && (
|
{tab === 'scenes' && !!tagsQuery.data?.items.length && (
|
||||||
<View style={styles.tagRow}>
|
<ScrollView
|
||||||
{tagsQuery.data.items.map((t) => (
|
horizontal
|
||||||
<Pressable
|
showsHorizontalScrollIndicator={false}
|
||||||
key={t.id}
|
contentContainerStyle={styles.tagRow}
|
||||||
style={styles.tagChip}
|
>
|
||||||
onPress={() =>
|
{tagsQuery.data.items.map((t) => {
|
||||||
navigation.push('TagScenes', { slug: t.slug, name: t.name })
|
const active = selectedTag?.slug === t.slug;
|
||||||
}
|
return (
|
||||||
>
|
<Pressable
|
||||||
<Text style={styles.tagChipText} numberOfLines={1}>
|
key={t.id}
|
||||||
{t.name}
|
style={[styles.tagChip, active && styles.tagChipActive]}
|
||||||
</Text>
|
onPress={() =>
|
||||||
</Pressable>
|
setSelectedTag(active ? null : { slug: t.slug, name: t.name })
|
||||||
))}
|
}
|
||||||
</View>
|
>
|
||||||
|
<Text
|
||||||
|
style={[styles.tagChipText, active && styles.tagChipTextActive]}
|
||||||
|
numberOfLines={1}
|
||||||
|
>
|
||||||
|
{active ? `${t.name} ✕` : t.name}
|
||||||
|
</Text>
|
||||||
|
</Pressable>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ScrollView>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
}
|
}
|
||||||
|
|
@ -418,10 +434,10 @@ const styles = StyleSheet.create({
|
||||||
actionBtnTextPrimary: { color: theme.accent, fontWeight: '700', fontSize: 12 },
|
actionBtnTextPrimary: { color: theme.accent, fontWeight: '700', fontSize: 12 },
|
||||||
tagRow: {
|
tagRow: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
flexWrap: 'wrap',
|
|
||||||
gap: 6,
|
gap: 6,
|
||||||
marginHorizontal: 4,
|
paddingHorizontal: 4,
|
||||||
marginBottom: 10,
|
paddingBottom: 10,
|
||||||
|
alignItems: 'center',
|
||||||
},
|
},
|
||||||
tagChip: {
|
tagChip: {
|
||||||
backgroundColor: theme.card,
|
backgroundColor: theme.card,
|
||||||
|
|
@ -430,9 +446,11 @@ const styles = StyleSheet.create({
|
||||||
borderRadius: 14,
|
borderRadius: 14,
|
||||||
paddingVertical: 4,
|
paddingVertical: 4,
|
||||||
paddingHorizontal: 10,
|
paddingHorizontal: 10,
|
||||||
maxWidth: 160,
|
maxWidth: 200,
|
||||||
},
|
},
|
||||||
|
tagChipActive: { backgroundColor: theme.accent, borderColor: theme.accent },
|
||||||
tagChipText: { color: theme.muted, fontSize: 12, fontWeight: '600' },
|
tagChipText: { color: theme.muted, fontSize: 12, fontWeight: '600' },
|
||||||
|
tagChipTextActive: { color: theme.fg, fontWeight: '700' },
|
||||||
tabRow: { flexDirection: 'row', gap: 8, marginBottom: 8 },
|
tabRow: { flexDirection: 'row', gap: 8, marginBottom: 8 },
|
||||||
tabBtn: {
|
tabBtn: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue