Auto-Commit: 2026-06-28 14:51:23

This commit is contained in:
2026-06-28 14:51:23 +02:00
parent 3271439a36
commit 0c9370f9f2
5 changed files with 19 additions and 21 deletions
+2 -2
View File
@@ -3,7 +3,7 @@
"newArchEnabled": true, "newArchEnabled": true,
"name": "Schnappix", "name": "Schnappix",
"slug": "Schnappix", "slug": "Schnappix",
"version": "23.01.10", "version": "23.01.11",
"orientation": "landscape", "orientation": "landscape",
"icon": "./Icon.png", "icon": "./Icon.png",
"userInterfaceStyle": "dark", "userInterfaceStyle": "dark",
@@ -13,7 +13,7 @@
}, },
"android": { "android": {
"package": "de.orfel.schnappix", "package": "de.orfel.schnappix",
"versionCode": 10, "versionCode": 11,
"adaptiveIcon": { "adaptiveIcon": {
"backgroundColor": "#050510", "backgroundColor": "#050510",
"foregroundImage": "./Icon-padded.png" "foregroundImage": "./Icon-padded.png"
+2 -6
View File
@@ -213,11 +213,7 @@ export default function AdminScreen({ currentSettings, onSave, onClose }: AdminS
const ipTrimmed = printerIp.trim(); const ipTrimmed = printerIp.trim();
const ipRegex = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/; const ipRegex = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/;
if (!ipTrimmed) { if (ipTrimmed !== '' && ipTrimmed !== '192.168.' && !ipRegex.test(ipTrimmed)) {
Alert.alert('Ungültige Eingabe', 'Die Drucker-IP-Adresse darf nicht leer sein.');
return;
}
if (!ipRegex.test(ipTrimmed)) {
Alert.alert('Ungültige Eingabe', 'Bitte gib eine gültige IP-Adresse ein (z.B. 192.168.1.100).'); Alert.alert('Ungültige Eingabe', 'Bitte gib eine gültige IP-Adresse ein (z.B. 192.168.1.100).');
return; return;
} }
@@ -254,7 +250,7 @@ export default function AdminScreen({ currentSettings, onSave, onClose }: AdminS
eventText: eventText.trim(), eventText: eventText.trim(),
burstCount: burst, burstCount: burst,
burstIntervalSec: interval, burstIntervalSec: interval,
welcomeText: welcomeText.trim() || 'Willkommen zu unserer Feier!', welcomeText: welcomeText.trim() || 'Zeit für ein Erinnerungsfoto!',
footerText: footerText.trim() || 'ZUM STARTEN TIPPEN • Fotos machen • Collage • Drucken', footerText: footerText.trim() || 'ZUM STARTEN TIPPEN • Fotos machen • Collage • Drucken',
useFrontCamera, useFrontCamera,
enableLogs, enableLogs,
+3 -3
View File
@@ -71,7 +71,7 @@ export default function CameraScreen({
onStartBooth, onStartBooth,
onNavigateToAdmin, onNavigateToAdmin,
adminPassword = '1234', adminPassword = '1234',
welcomeText = 'Willkommen zu unserer Feier!', welcomeText = 'Zeit für ein Erinnerungsfoto!',
burstCount = 1, burstCount = 1,
burstIntervalSec, burstIntervalSec,
frameMode, frameMode,
@@ -344,7 +344,7 @@ export default function CameraScreen({
}); });
capturedUri = photo.uri; capturedUri = photo.uri;
} else { } else {
throw new Error('Kamera-Referenz ist nicht verfügbar.'); throw new Error('Kamera-Referenz ist nicht verfügbar. Bitte stelle sicher, dass die externe Kamera verbunden ist, oder aktiviere den Front-Kamera-Fallback in den Admin-Einstellungen.');
} }
} }
@@ -671,7 +671,7 @@ export default function CameraScreen({
{/* Camera Preview Background */} {/* Camera Preview Background */}
<View style={styles.previewContainer}> <View style={styles.previewContainer}>
<View style={styles.cameraWrapper}> <View style={styles.cameraWrapper}>
{!isObscured && Platform.OS === 'android' && !useFrontCamera ? ( {Platform.OS === 'android' && !useFrontCamera ? (
<UsbCameraView <UsbCameraView
ref={usbCameraRef} ref={usbCameraRef}
style={StyleSheet.absoluteFill} style={StyleSheet.absoluteFill}
+11 -9
View File
@@ -1,5 +1,5 @@
import React, { useState, useRef, useCallback, useEffect } from 'react'; import React, { useState, useRef, useCallback, useEffect } from 'react';
import { ScrollView, StyleSheet, Text, View, Image, TouchableOpacity, ActivityIndicator, BackHandler } from 'react-native'; import { ScrollView, StyleSheet, Text, View, Image, TouchableOpacity, ActivityIndicator, BackHandler, useWindowDimensions } from 'react-native';
import ViewShot from 'react-native-view-shot'; import ViewShot from 'react-native-view-shot';
import { LinearGradient } from 'expo-linear-gradient'; import { LinearGradient } from 'expo-linear-gradient';
import Animated, { FadeIn, FadeOut } from 'react-native-reanimated'; import Animated, { FadeIn, FadeOut } from 'react-native-reanimated';
@@ -61,6 +61,9 @@ export default function PreviewScreen({
const [isCapturing, setIsCapturing] = useState<boolean>(false); const [isCapturing, setIsCapturing] = useState<boolean>(false);
const [statusMessage, setStatusMessage] = useState<string>(''); const [statusMessage, setStatusMessage] = useState<string>('');
const { width, height } = useWindowDimensions();
const isPortrait = height > width;
const [activeUris, setActiveUris] = useState<string[]>([]); const [activeUris, setActiveUris] = useState<string[]>([]);
// Initialize activeUris with all available photos up to 4 when first loaded // Initialize activeUris with all available photos up to 4 when first loaded
@@ -466,12 +469,12 @@ export default function PreviewScreen({
return ( return (
<View <View
style={styles.container} style={[styles.container, { flexDirection: isPortrait ? 'column' : 'row' }]}
onTouchStart={resetIdleTimer} onTouchStart={resetIdleTimer}
> >
{/* Left panel: Preview Canvas */} {/* Left panel: Preview Canvas */}
<TouchableOpacity <TouchableOpacity
style={styles.previewPanel} style={[styles.previewPanel, { flex: isPortrait ? 1 : 1.2 }]}
activeOpacity={1} activeOpacity={1}
onPress={handleCanvasPress} onPress={handleCanvasPress}
> >
@@ -533,7 +536,10 @@ export default function PreviewScreen({
)} )}
{/* Right panel: Controls */} {/* Right panel: Controls */}
<View style={styles.controlPanel}> <ScrollView
style={[styles.controlPanel, { flex: isPortrait ? 1 : 0.8 }]}
contentContainerStyle={{ flexGrow: 1, justifyContent: 'center' }}
>
<Text style={styles.header}>{eventText}</Text> <Text style={styles.header}>{eventText}</Text>
{/* Thumbnail Reel for Photo Selection */} {/* Thumbnail Reel for Photo Selection */}
@@ -660,7 +666,7 @@ export default function PreviewScreen({
</TouchableOpacity> </TouchableOpacity>
</View> </View>
</View> </View>
</View> </ScrollView>
{/* Loading Overlay */} {/* Loading Overlay */}
{isProcessing && ( {isProcessing && (
@@ -678,11 +684,9 @@ export default function PreviewScreen({
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
flexDirection: 'row',
backgroundColor: THEME.colors.background, backgroundColor: THEME.colors.background,
}, },
previewPanel: { previewPanel: {
flex: 1.2,
justifyContent: 'flex-start', justifyContent: 'flex-start',
alignItems: 'center', alignItems: 'center',
padding: THEME.spacing.md, padding: THEME.spacing.md,
@@ -698,10 +702,8 @@ const styles = StyleSheet.create({
overflow: 'hidden', overflow: 'hidden',
}, },
controlPanel: { controlPanel: {
flex: 0.8,
backgroundColor: THEME.colors.surface, backgroundColor: THEME.colors.surface,
padding: THEME.spacing.xl, padding: THEME.spacing.xl,
justifyContent: 'center',
borderLeftWidth: 1, borderLeftWidth: 1,
borderColor: THEME.colors.border, borderColor: THEME.colors.border,
}, },
+1 -1
View File
@@ -35,7 +35,7 @@ const settingsFile = new File(Paths.document, 'settings.json');
const DEFAULT_SETTINGS: AppSettings = { const DEFAULT_SETTINGS: AppSettings = {
appLastUpdate: null, appLastUpdate: null,
countdownDuration: 3, countdownDuration: 3,
printerIp: '192.168.1.100', printerIp: '192.168.',
adminPassword: '1234', adminPassword: '1234',
kioskModeEnabled: false, kioskModeEnabled: false,
frameMode: 'available', frameMode: 'available',