feat(app): Pinch-Zoom + Pan im Vollbild-Modal
Neue ZoomableImage-Komponente — reine RN-Implementation mit PanResponder + Animated, ohne extra Dependency. - 2-Finger-Pinch: Zoom 1x..5x, Focal-Point folgt der Geste - 1-Finger-Pan: nur aktiv wenn gezoomt, mit Bounds-Clamping - Doppel-Tap: Toggle 1x ↔ 2.5x Vollbild-Modal ersetzt das simple <Image> durch ZoomableImage fuer JPEG/PNG/etc. SVGs bleiben non-zoomable (SvgUri-Limitation), Tap schliesst sie. Plus dedicated ✕-Close-Button oben rechts da Tap-to- Close mit PanResponder kollidiert. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,8 @@ import {
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import RNFS from 'react-native-fs';
|
||||
import { SvgUri } from 'react-native-svg';
|
||||
import { Dimensions } from 'react-native';
|
||||
import ZoomableImage from '../components/ZoomableImage';
|
||||
import rvs, { RVSMessage, ConnectionState } from '../services/rvs';
|
||||
import audioService from '../services/audio';
|
||||
import wakeWordService from '../services/wakeword';
|
||||
@@ -1378,25 +1380,32 @@ const ChatScreen: React.FC = () => {
|
||||
|
||||
{/* Bild-Vollbild Modal */}
|
||||
<Modal visible={!!fullscreenImage} transparent animationType="fade" onRequestClose={() => setFullscreenImage(null)}>
|
||||
<TouchableOpacity
|
||||
style={styles.fullscreenOverlay}
|
||||
activeOpacity={1}
|
||||
onPress={() => setFullscreenImage(null)}
|
||||
>
|
||||
<View style={styles.fullscreenOverlay}>
|
||||
{fullscreenImage && (
|
||||
/\.svg(?:\?|$)/i.test(fullscreenImage) ? (
|
||||
<View style={styles.fullscreenImage}>
|
||||
// SVG: bisher keine Pinch-Zoom — Tap zum Schliessen
|
||||
<TouchableOpacity style={styles.fullscreenImage} activeOpacity={1} onPress={() => setFullscreenImage(null)}>
|
||||
<SvgUri uri={fullscreenImage} width="100%" height="100%" preserveAspectRatio="xMidYMid meet" />
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
<Image
|
||||
source={{ uri: fullscreenImage }}
|
||||
// Pixel-Bild: Pinch-Zoom + Pan ueber ZoomableImage
|
||||
<ZoomableImage
|
||||
uri={fullscreenImage}
|
||||
containerWidth={Dimensions.get('window').width}
|
||||
containerHeight={Dimensions.get('window').height}
|
||||
style={styles.fullscreenImage}
|
||||
resizeMode="contain"
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
{/* Close-Button oben rechts — die TouchableOpacity-uebergreifend funktioniert
|
||||
wegen ZoomableImage-PanResponder nicht zuverlaessig fuer Tap-to-Close */}
|
||||
<TouchableOpacity
|
||||
style={{ position: 'absolute', top: 32, right: 16, padding: 12, backgroundColor: 'rgba(0,0,0,0.5)', borderRadius: 24 }}
|
||||
onPress={() => setFullscreenImage(null)}
|
||||
>
|
||||
<Text style={{ color: '#FFF', fontSize: 22 }}>{'✕'}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</Modal>
|
||||
|
||||
{/* Datei-Upload Modal */}
|
||||
|
||||
Reference in New Issue
Block a user