Verbesserungen: Admin-Passwort Hinweis, Mobile Skalierung in PreviewScreen, Rahmen-Menü Toggle, Footer Layout Fix
This commit is contained in:
@@ -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.
|
||||
@@ -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}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user