Verbesserungen: Admin-Passwort Hinweis, Mobile Skalierung in PreviewScreen, Rahmen-Menü Toggle, Footer Layout Fix

This commit is contained in:
2026-07-04 19:56:50 +02:00
parent 4be915ef90
commit 715b2679f1
3 changed files with 34 additions and 21 deletions
+6
View File
@@ -0,0 +1,6 @@
# Versioning & Build Rules Addendum
## Build Configuration
- The app MUST ALWAYS be signed with `schnappix-upload-key.keystore`. This is handled automatically by the custom Expo plugin `withAndroidSigning.js`. Do not modify or remove this plugin.
- The `schnappix-upload-key.keystore` file is checked into the Git repository. Do NOT delete it, ignore it in git, or change its password (`#O0he7k00O0he7k00!`).
- The Expo Media Library plugin injects `READ_MEDIA_IMAGES` and `READ_MEDIA_VIDEO` permissions into the Android manifest by default. These are rejected by Google Play for this specific app. To prevent this, the `withRemoveMediaPermissions.js` plugin MUST ALWAYS be included in `app.json`. This plugin forcibly strips these permissions using Android's `tools:node="remove"` directive during compilation. Do not remove this plugin.
+8 -3
View File
@@ -9,6 +9,7 @@ import {
TextInput,
TouchableWithoutFeedback,
PermissionsAndroid,
useWindowDimensions,
} from 'react-native';
import { CameraView, useCameraPermissions } from 'expo-camera';
import * as FileSystem from 'expo-file-system/legacy';
@@ -110,6 +111,9 @@ export default function CameraScreen({
const completionTimerRef = useRef<any>(null);
const isCancelledRef = useRef<boolean>(false);
const { width } = useWindowDimensions();
const iconSize = width < 768 ? 18 : 32;
// Reanimated countdown pulse animation
const scale = useSharedValue(1);
@@ -538,9 +542,7 @@ export default function CameraScreen({
>
{footerText === 'Display tippen! • Lächeln! • Foto schnappen!' ? (
<Text>
<FontAwesomeIcon icon={faHandPointer} color={THEME.colors.text} size={32} />Display tippen!
<FontAwesomeIcon icon={faFaceSmile} color={THEME.colors.text} size={32} />Lächeln!
<FontAwesomeIcon icon={faCamera} color={THEME.colors.text} size={32} />Foto schnappen!
<FontAwesomeIcon icon={faHandPointer} color={THEME.colors.text} size={iconSize} /> Display tippen! <FontAwesomeIcon icon={faFaceSmile} color={THEME.colors.text} size={iconSize} /> Lächeln! <FontAwesomeIcon icon={faCamera} color={THEME.colors.text} size={iconSize} /> Foto schnappen!
</Text>
) : (
footerText
@@ -559,6 +561,9 @@ export default function CameraScreen({
<View style={styles.modalContent}>
<Text style={styles.modalTitle}>Admin-Zugang</Text>
<Text style={styles.modalSub}>Passwort eingeben, um Einstellungen zu öffnen</Text>
<Text style={[styles.modalSub, { color: THEME.colors.error, marginTop: 10, fontSize: 14, fontStyle: 'italic' }]}>
Tipp: Standardcode ist 1234. Bitte ändern! Ein Zurücksetzen ist nur durch Neuinstallation der App möglich.
</Text>
<TextInput
style={styles.input}
+20 -18
View File
@@ -63,6 +63,7 @@ export default function PreviewScreen({
const { width, height } = useWindowDimensions();
const isPortrait = height > width;
const isSmallDevice = width < 768;
const [activeUris, setActiveUris] = useState<string[]>([]);
@@ -117,6 +118,7 @@ export default function PreviewScreen({
};
}, []);
const [showStickerTray, setShowStickerTray] = useState<boolean>(false);
const [showFrameTray, setShowFrameTray] = useState<boolean>(false);
React.useEffect(() => {
logger.log(`PreviewScreen mounted with ${photoUris.length} photos.`);
@@ -537,10 +539,10 @@ export default function PreviewScreen({
{/* Right panel: Controls */}
<ScrollView
style={[styles.controlPanel, { flex: isPortrait ? 1 : 0.8 }]}
style={[styles.controlPanel, { flex: isPortrait ? 1 : 0.8, padding: isSmallDevice ? THEME.spacing.md : THEME.spacing.xl }]}
contentContainerStyle={{ flexGrow: 1, justifyContent: 'center' }}
>
<Text style={styles.header}>{eventText}</Text>
<Text style={[styles.header, isSmallDevice && { fontSize: 18, marginBottom: THEME.spacing.sm }]}>{eventText}</Text>
{/* Thumbnail Reel for Photo Selection */}
{photoUris.length > 1 && (
@@ -581,8 +583,12 @@ export default function PreviewScreen({
{/* Editing Tools Row */}
<View style={styles.editToolsRow}>
<TouchableOpacity
style={[styles.editToolBtn, showStickerTray && styles.editToolBtnActive]}
onPress={() => { logger.log(`Action: Toggled sticker tray ${!showStickerTray}`); setShowStickerTray(!showStickerTray); }}
style={[styles.editToolBtn, isSmallDevice && { paddingVertical: 8, paddingHorizontal: 12 }, showStickerTray && styles.editToolBtnActive]}
onPress={() => {
logger.log(`Action: Toggled sticker tray ${!showStickerTray}`);
setShowStickerTray(!showStickerTray);
if (!showStickerTray) setShowFrameTray(false);
}}
>
<FontAwesomeIcon
icon={faFaceGrinStars}
@@ -596,23 +602,19 @@ export default function PreviewScreen({
{frameMode === 'available' && (
<TouchableOpacity
style={[styles.editToolBtn, selectedFrameId !== null && styles.editToolBtnActive]}
style={[styles.editToolBtn, isSmallDevice && { paddingVertical: 8, paddingHorizontal: 12 }, showFrameTray && styles.editToolBtnActive]}
onPress={() => {
if (selectedFrameId !== null) {
logger.log('Action: Removed frame');
setSelectedFrameId(null);
} else {
logger.log('Action: Toggled frame selection');
}
// FramePicker is shown below
logger.log(`Action: Toggled frame tray ${!showFrameTray}`);
setShowFrameTray(!showFrameTray);
if (!showFrameTray) setShowStickerTray(false);
}}
>
<FontAwesomeIcon
icon={faBorderAll}
size={22}
color={selectedFrameId !== null ? THEME.colors.text : THEME.colors.accent}
color={showFrameTray ? THEME.colors.text : THEME.colors.accent}
/>
<Text style={[styles.editToolText, selectedFrameId !== null && styles.editToolTextActive]}>
<Text style={[styles.editToolText, showFrameTray && styles.editToolTextActive]}>
Rahmen
</Text>
</TouchableOpacity>
@@ -620,7 +622,7 @@ export default function PreviewScreen({
</View>
{/* Frame Picker (when mode = available) */}
{frameMode === 'available' && (
{frameMode === 'available' && showFrameTray && (
<FramePicker
selectedFrameId={selectedFrameId}
onSelectFrame={(id) => {
@@ -633,12 +635,12 @@ export default function PreviewScreen({
{/* Action Buttons */}
<View style={styles.actions}>
<TouchableOpacity style={[styles.actionBtn, styles.printBtn, isProcessing && styles.btnDisabled]} onPress={handlePrint} activeOpacity={0.8} disabled={isProcessing}>
<TouchableOpacity style={[styles.actionBtn, styles.printBtn, isProcessing && styles.btnDisabled, isSmallDevice && { marginBottom: THEME.spacing.sm }]} onPress={handlePrint} activeOpacity={0.8} disabled={isProcessing}>
<LinearGradient
colors={THEME.gradient.primary}
start={{ x: 0, y: 0.5 }}
end={{ x: 1, y: 0.5 }}
style={styles.printGradient}
style={[styles.printGradient, isSmallDevice && { paddingVertical: THEME.spacing.sm }]}
>
<FontAwesomeIcon icon={faPrint} size={18} color={THEME.colors.text} style={{ marginRight: 8 }} />
<Text style={styles.actionBtnText}>JETZT DRUCKEN</Text>
@@ -648,7 +650,7 @@ export default function PreviewScreen({
{photoUris.length < 4 && (
<TouchableOpacity style={[styles.actionBtn, styles.addBtn, isProcessing && styles.btnDisabled]} onPress={onAddAnother} disabled={isProcessing}>
<TouchableOpacity style={[styles.actionBtn, styles.addBtn, isProcessing && styles.btnDisabled, isSmallDevice && { paddingVertical: THEME.spacing.sm, marginBottom: THEME.spacing.sm }]} onPress={onAddAnother} disabled={isProcessing}>
<FontAwesomeIcon icon={faPlus} size={16} color={THEME.colors.text} style={{ marginRight: 8 }} />
<Text style={styles.actionBtnText}>Weiteres Foto aufnehmen</Text>
</TouchableOpacity>