diff --git a/App.tsx b/App.tsx
index eecc29bf..b935dfa6 100644
--- a/App.tsx
+++ b/App.tsx
@@ -59,12 +59,8 @@ export default function App() {
updatedUris.pop();
setPhotoUris(updatedUris);
- // If we have other photos, let user retake from current collage length
- if (updatedUris.length > 0) {
- setCurrentScreen('camera');
- } else {
- setCurrentScreen('home');
- }
+ // Always let user retake
+ setCurrentScreen('camera');
};
const handleAddAnother = () => {
diff --git a/app.json b/app.json
index 965962ce..15b1ee5f 100644
--- a/app.json
+++ b/app.json
@@ -12,10 +12,6 @@
},
"android": {
"package": "com.schnappix",
- "adaptiveIcon": {
- "backgroundColor": "#050510",
- "foregroundImage": "./Icon.png"
- },
"permissions": [
"android.permission.CAMERA",
"android.permission.RECORD_AUDIO",
diff --git a/src/screens/CameraScreen.tsx b/src/screens/CameraScreen.tsx
index 46512ed4..dccb7bb7 100644
--- a/src/screens/CameraScreen.tsx
+++ b/src/screens/CameraScreen.tsx
@@ -272,6 +272,15 @@ export default function CameraScreen({
}
};
+ const handleCancel = useCallback(() => {
+ if (burstTimerRef.current) {
+ clearTimeout(burstTimerRef.current);
+ }
+ setHasStarted(false);
+ setIsCapturing(false);
+ onCancel();
+ }, [onCancel]);
+
const handleSettingsTap = () => {
setEnteredPassword('');
setErrorText('');
@@ -327,24 +336,13 @@ export default function CameraScreen({
-
- SCHNAPPIX
- {welcomeText}
-
-
-
-
-
- ZUM STARTEN ÜBERALL TIPPEN
-
-
- Fotos machen • Collage erstellen • Sofort drucken
-
+ {/* Header Event Text */}
+ {welcomeText}
+
+ {/* Footer Instructions */}
+
+ ZUM STARTEN TIPPEN • Fotos machen • Collage • Drucken
+
{/* Password Prompt Modal */}
+
ABBRECHEN
@@ -530,10 +528,12 @@ const styles = StyleSheet.create({
zIndex: 9999,
},
idleOverlayContainer: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'center',
- backgroundColor: 'rgba(5, 5, 16, 0.25)',
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ right: 0,
+ bottom: 0,
+ backgroundColor: 'transparent',
},
captureOverlayContainer: {
flex: 1,
@@ -554,73 +554,31 @@ const styles = StyleSheet.create({
alignItems: 'center',
zIndex: 999,
},
- welcomeBox: {
- alignItems: 'center',
- padding: THEME.spacing.xl,
- borderRadius: THEME.borderRadius.lg,
- backgroundColor: 'rgba(5, 5, 16, 0.85)',
- borderWidth: 1,
- borderColor: THEME.colors.gradientBorder,
- width: '60%',
- shadowColor: THEME.colors.gradientGlow,
- shadowOffset: { width: 0, height: 0 },
- shadowOpacity: 0.4,
- shadowRadius: 30,
- elevation: 10,
- },
- logo: {
- fontSize: 54,
+ headerTitle: {
+ position: 'absolute',
+ top: 40,
+ width: '100%',
+ textAlign: 'center',
+ fontSize: 48,
fontWeight: '900',
color: THEME.colors.accent,
- letterSpacing: 8,
- marginBottom: THEME.spacing.sm,
+ letterSpacing: 6,
textShadowColor: THEME.colors.cyanGlow,
textShadowOffset: { width: 0, height: 0 },
textShadowRadius: 25,
},
- welcomeTitle: {
- fontSize: 22,
- color: THEME.colors.text,
+ footerInstructions: {
+ position: 'absolute',
+ bottom: 40,
+ width: '100%',
textAlign: 'center',
- marginBottom: THEME.spacing.lg,
- letterSpacing: 1,
- },
- divider: {
- width: 60,
- height: 3,
- backgroundColor: THEME.colors.accent,
- marginBottom: THEME.spacing.xl,
- borderRadius: THEME.borderRadius.sm,
- shadowColor: THEME.colors.accent,
- shadowOffset: { width: 0, height: 0 },
- shadowOpacity: 0.8,
- shadowRadius: 8,
- },
- startButton: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'center',
- paddingVertical: THEME.spacing.md,
- paddingHorizontal: THEME.spacing.xl,
- borderRadius: THEME.borderRadius.round,
- marginBottom: THEME.spacing.xl,
- overflow: 'hidden',
- shadowColor: THEME.colors.gradientGlow,
- shadowOffset: { width: 0, height: 4 },
- shadowOpacity: 0.6,
- shadowRadius: 14,
- elevation: 8,
- },
- startButtonText: {
- color: THEME.colors.text,
- fontSize: 18,
+ fontSize: 20,
fontWeight: 'bold',
+ color: THEME.colors.text,
letterSpacing: 2,
- },
- welcomeFooter: {
- fontSize: 14,
- color: THEME.colors.textMuted,
- letterSpacing: 1,
+ textShadowColor: 'rgba(0,0,0,0.9)',
+ textShadowOffset: { width: 0, height: 2 },
+ textShadowRadius: 15,
},
hudContainer: {
position: 'absolute',
@@ -838,6 +796,8 @@ const styles = StyleSheet.create({
},
confirmGradient: {
flex: 1,
+ width: '100%',
+ height: '100%',
alignItems: 'center',
justifyContent: 'center',
},
diff --git a/src/screens/PreviewScreen.tsx b/src/screens/PreviewScreen.tsx
index 2b3c9072..5da298d8 100644
--- a/src/screens/PreviewScreen.tsx
+++ b/src/screens/PreviewScreen.tsx
@@ -70,6 +70,9 @@ export default function PreviewScreen({
const [selectedStickerId, setSelectedStickerId] = useState(null);
const [showStickerTray, setShowStickerTray] = useState(false);
+ // Idle Timer state
+ const idleTimerRef = useRef(null);
+
// Frame state
const [selectedFrameId, setSelectedFrameId] = useState(
frameMode === 'always' ? initialFrameId : null
@@ -227,7 +230,7 @@ export default function PreviewScreen({
};
// Auto-save and exit
- const handleExit = async () => {
+ const handleExit = useCallback(async () => {
if (stickers.length === 0 && layout === 'single' && !activeFrame && dateOverlay === 'off') {
onReset();
return;
@@ -248,6 +251,36 @@ export default function PreviewScreen({
setIsProcessing(false);
onReset();
}
+ }, [stickers, layout, activeFrame, dateOverlay, onReset]);
+
+ // Idle timer logic
+ const resetIdleTimer = useCallback(() => {
+ if (idleTimerRef.current) clearTimeout(idleTimerRef.current);
+ idleTimerRef.current = setTimeout(() => {
+ handleExit();
+ }, 60000);
+ }, [handleExit]);
+
+ useEffect(() => {
+ resetIdleTimer();
+ return () => {
+ if (idleTimerRef.current) clearTimeout(idleTimerRef.current);
+ };
+ }, [resetIdleTimer]);
+
+ const handleRetakeClick = async () => {
+ if (stickers.length > 0 || layout !== 'single' || activeFrame || dateOverlay !== 'off') {
+ setIsProcessing(true);
+ setStatusMessage('Wird vor dem Wiederholen gespeichert...');
+ try {
+ const capturedUri = await captureComposite();
+ await saveToGallery(capturedUri);
+ } catch (error) {
+ console.error('Auto-saving before retake failed:', error);
+ }
+ setIsProcessing(false);
+ }
+ onRetakeLast();
};
// ── Render the collage ──
@@ -303,7 +336,12 @@ export default function PreviewScreen({
};
return (
-
+
{/* Left panel: Preview Canvas */}
-
+
Wiederholen
@@ -686,7 +724,7 @@ const styles = StyleSheet.create({
width: 480,
height: 320,
backgroundColor: '#fff',
- padding: 10,
+ padding: 0,
shadowColor: THEME.colors.gradientGlow,
shadowOffset: { width: 0, height: 0 },
shadowOpacity: 0.35,
diff --git a/src/services/settings.ts b/src/services/settings.ts
index e3a1644a..c255ab5a 100644
--- a/src/services/settings.ts
+++ b/src/services/settings.ts
@@ -1,4 +1,6 @@
import { File, Paths } from 'expo-file-system';
+import * as FileSystem from 'expo-file-system';
+import { FRAMES } from '../data/frames';
export interface AppSettings {
countdownDuration: number; // in seconds
@@ -28,9 +30,9 @@ const DEFAULT_SETTINGS: AppSettings = {
printerIp: '192.168.1.100',
adminPassword: '1234',
kioskModeEnabled: false,
- frameMode: 'off',
+ frameMode: 'available',
selectedFrameId: null,
- availableFrameIds: [],
+ availableFrameIds: FRAMES.map(f => f.id),
dateOverlay: 'off',
dateOverlayPosition: 'bottom-right',
eventText: '',
@@ -61,7 +63,7 @@ export async function loadSettings(): Promise {
export async function saveSettings(settings: AppSettings): Promise {
try {
const content = JSON.stringify(settings, null, 2);
- settingsFile.write(content);
+ await FileSystem.writeAsStringAsync(settingsFile.uri, content);
console.log('Settings saved successfully:', content);
} catch (e) {
console.error('Failed to save settings:', e);