Auto-Commit: 2026-06-28 14:51:23
This commit is contained in:
@@ -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"
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
Reference in New Issue
Block a user