feat(mobile): add multi-image indicator to feed posts

Multi-photo posts gave no visual hint they were swipeable — a viewer
would only ever see the first image unless they already knew to swipe.
Adds a "1 / N" counter badge (top-right overlay) and a dot-page
indicator below the carousel, porting web's PostCard indicators.
This commit is contained in:
admin committed 2026-09-06 20:12:21 +02:00
1 parent 086b0e8900
commit 82c9bb87b9
2 files changed
+58 -10

No files matched your search

+4 -5
View File
@@ -34,10 +34,9 @@ TODO Neu2:
→ Sichtbare Trennlinie zwischen den Einträgen ergänzt, live bestätigt.
- [x] Benachrichtigungen sind nicht anklickbar, sollten aber zu dem jeweiligen Post / Pet gehen.
→ Tap markiert als gelesen und navigiert zum Ziel (Post-Kommentare bzw. Tierprofil je nach Typ), live bestätigt.
→ Nachbesserung: Alle Post-Benachrichtigungen zeigten nur die leere Kommentarliste statt des Beitrags selbst — die Kommentar-Seite lädt jetzt zusätzlich den Post (posts.getById) und zeigt ihn oben per PostCard an. Außerdem ist der Pet-Name in der Benachrichtigung jetzt separat anklickbar zum Profil, unabhängig vom restlichen Zeilen-Tap. Beides live bestätigt.
- [x] Drei Punkte, menü im Feed, falls es der eigene Beitrag ist, lösch funktion hinzufügen, statt Report.
→ Bei eigenem Beitrag öffnet "⋮" jetzt einen Lösch-Bestätigungsdialog statt der Report-Ansicht, bei fremden Beiträgen bleibt Report wie gewohnt; beides live bestätigt.
- im Feed fehlt ein Indikator wenn in einem Post mehrere Bilder hinterlegt sind. das wischen funktioniert, aber nur wenn man weiß das dort mehrere bilder hinterlegt sind. unwissende würde nur ein bild sehen können.
- [x] Kommentar Fenster ist nicht im Darkmode
→ Screen nutzte noch die statischen (hellen) Farb-Tokens statt useTheme(); jetzt vollständig dark-mode-fähig, live bestätigt.
-
- [x] im Feed fehlt ein Indikator wenn in einem Post mehrere Bilder hinterlegt sind. das wischen funktioniert, aber nur wenn man weiß das dort mehrere bilder hinterlegt sind. unwissende würde nur ein bild sehen können.
→ Zähler-Badge oben rechts ("1 / 3") plus Punkte-Indikator unter dem Bild ergänzt (analog zur Web-Version), live bestätigt.
- [x] Kommentar Fenster ist nicht im Darkmode
-
+54 -5
View File
@@ -184,7 +184,16 @@ type PostImagesProps = {
onPressImage: (index: number) => void;
};
/**
* found.md: a multi-image post gave no visual hint it was swipeable — a
* viewer would only ever see the first photo unless they already knew to
* swipe. Ports web's PostCard indicators (index badge top-right + dots
* below) so the carousel is discoverable at a glance.
*/
function PostImages({ images, width, onPressImage }: PostImagesProps) {
const { colors } = useTheme();
const [index, setIndex] = useState(0);
if (images.length === 0) return null;
if (images.length === 1) {
@@ -192,14 +201,54 @@ function PostImages({ images, width, onPressImage }: PostImagesProps) {
}
return (
<ScrollView horizontal pagingEnabled showsHorizontalScrollIndicator={false} style={{ width }}>
{images.map((image, index) => (
<PostImage key={image.id} image={image} width={width} onPress={() => onPressImage(index)} />
))}
</ScrollView>
<View>
<View style={{ width }}>
<ScrollView
horizontal
pagingEnabled
showsHorizontalScrollIndicator={false}
onMomentumScrollEnd={(e) => setIndex(Math.round(e.nativeEvent.contentOffset.x / width))}
>
{images.map((image, i) => (
<PostImage key={image.id} image={image} width={width} onPress={() => onPressImage(i)} />
))}
</ScrollView>
<View style={multiImageStyles.counterBadge}>
<Text style={multiImageStyles.counterText}>
{index + 1} / {images.length}
</Text>
</View>
</View>
<View style={multiImageStyles.dotsRow}>
{images.map((_, i) => (
<View
key={i}
style={[
multiImageStyles.dot,
{ backgroundColor: i === index ? colors.ink : colors.hairlineGray },
]}
/>
))}
</View>
</View>
);
}
const multiImageStyles = StyleSheet.create({
counterBadge: {
position: "absolute",
top: 8,
right: 8,
backgroundColor: "rgba(0,0,0,0.5)",
borderRadius: radii.sm,
paddingHorizontal: 6,
paddingVertical: 2,
},
counterText: { color: "#fff", fontSize: 11 },
dotsRow: { flexDirection: "row", justifyContent: "center", alignItems: "center", gap: 6, paddingVertical: 8 },
dot: { width: 6, height: 6, borderRadius: 3 },
});
function PostImage({ image, width, onPress }: { image: PostCardImage; width: number; onPress: () => void }) {
const rawRatio = image.width && image.height ? image.width / image.height : 1;
const aspectRatio = Math.min(1.91, Math.max(0.75, rawRatio));