/** * MessageText — selektierbarer Chat-Text mit Android-Auto-Linkifizierung, * plus Inline-Image-Rendering wenn der Text Bild-URLs enthaelt. * * - Markdown-Syntax `![alt](url)` und plain `https://...image.png` werden * erkannt — die URL bleibt im Text sichtbar (klickbar via Linkify), * zusaetzlich wird das Bild als oder drunter gerendert. * - Wir nutzen Androids dataDetectorType="all" (System macht Phone/URL/Email * automatisch klickbar) und ein einzelnes ohne nested * mit eigenem onPress — Nested Text mit onPress fing die Long-Press- * Geste ab, damit war Markieren+Kopieren defekt. */ import React, { useEffect, useState } from 'react'; import { View, Text, Image, TextStyle, StyleProp } from 'react-native'; import { SvgUri } from 'react-native-svg'; interface Props { text: string; style?: StyleProp; } // Bild-URL-Pattern: http(s)://... endend auf gaengige Bild-Endungen. const IMG_URL_RE = /https?:\/\/[^\s)<"']+\.(?:jpe?g|png|gif|webp|bmp|ico|svg)(?:\?[^\s)<"']*)?/gi; function extractImageUrls(text: string): string[] { const urls = new Set(); const matches = text.match(IMG_URL_RE); if (matches) matches.forEach(u => urls.add(u)); return Array.from(urls); } const SVG_RE = /\.svg(?:\?|$)/i; /** Image mit dynamischer Aspect-Ratio aus echten Bilddimensionen. * SVGs werden ueber react-native-svg gerendert (kein Image.getSize). */ const InlineImage: React.FC<{ uri: string }> = ({ uri }) => { const isSvg = SVG_RE.test(uri); const [aspectRatio, setAspectRatio] = useState(1); const [failed, setFailed] = useState(false); useEffect(() => { if (isSvg) return; // Image.getSize geht fuer SVG nicht let cancelled = false; Image.getSize( uri, (w, h) => { if (!cancelled && w > 0 && h > 0) setAspectRatio(Math.max(0.5, Math.min(2.5, w / h))); }, () => { if (!cancelled) setFailed(true); }, ); return () => { cancelled = true; }; }, [uri, isSvg]); if (failed) return null; if (isSvg) { return ( setFailed(true)} /> ); } return ( setFailed(true)} /> ); }; const MessageText: React.FC = ({ text, style }) => { const imageUrls = extractImageUrls(text || ''); if (imageUrls.length === 0) { return ( {text} ); } return ( {text} {imageUrls.map(u => )} ); }; export default MessageText;