Update default texts, admin UI improvements, Kiosk Mode prep, and fix image gallery saving

This commit is contained in:
2026-06-12 23:02:30 +02:00
parent eee19ad208
commit c05b71b53d
52 changed files with 1027 additions and 31 deletions
+8 -4
View File
@@ -11,6 +11,7 @@ import {
Modal,
BackHandler,
PanResponder,
Linking,
} from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
import Animated, { FadeIn, FadeOut } from 'react-native-reanimated';
@@ -347,7 +348,7 @@ export default function AdminScreen({ currentSettings, onSave, onClose }: AdminS
<Text style={styles.label}>Begrüßungstext</Text>
<TextInput
style={styles.input}
placeholder="Willkommen zu unserer Feier!"
placeholder="Zeit für ein Erinnerungsfoto!"
placeholderTextColor={THEME.colors.textMuted}
value={welcomeText}
onChangeText={setWelcomeText}
@@ -357,7 +358,7 @@ export default function AdminScreen({ currentSettings, onSave, onClose }: AdminS
<Text style={styles.label}>Subtext (Footer)</Text>
<TextInput
style={styles.input}
placeholder="ZUM STARTEN TIPPEN..."
placeholder="👆 Display tippen! • 😊 Lächeln! • 📸 Foto schnappen!"
placeholderTextColor={THEME.colors.textMuted}
value={footerText}
onChangeText={setFooterText}
@@ -367,7 +368,7 @@ export default function AdminScreen({ currentSettings, onSave, onClose }: AdminS
<Text style={styles.label}>Event-Name (wird auch im Datum-Sticker & Collage verwendet)</Text>
<TextInput
style={styles.input}
placeholder="z.B. Jannik's Party"
placeholder="Schnappix-Party"
placeholderTextColor={THEME.colors.textMuted}
value={eventText}
onChangeText={setEventText}
@@ -662,7 +663,10 @@ export default function AdminScreen({ currentSettings, onSave, onClose }: AdminS
</TouchableOpacity>
<View style={{ alignItems: 'center', marginTop: 20, marginBottom: 40 }}>
<Text style={{ color: '#555', fontSize: 14 }}>App Version {appConfig.expo.version}</Text>
<Text style={{ color: '#555', fontSize: 14, marginBottom: 10 }}>App Version {appConfig.expo.version}</Text>
<TouchableOpacity onPress={() => Linking.openURL('https://schnappix.orfel.de')}>
<Text style={{ color: THEME.colors.accent, fontSize: 16, textDecorationLine: 'underline' }}>schnappix.orfel.de</Text>
</TouchableOpacity>
</View>
</ScrollView>
+3 -3
View File
@@ -43,11 +43,11 @@ const DEFAULT_SETTINGS: AppSettings = {
availableFrameIds: FRAMES.map(f => f.id),
dateOverlay: 'off',
dateOverlayTransform: { x: 0, y: 0, rotation: 0, scale: 1 },
eventText: '',
eventText: 'Schnappix-Party',
burstCount: 1,
burstIntervalSec: 5,
welcomeText: 'Willkommen zu unserer Feier!',
footerText: 'ZUM STARTEN TIPPEN • Fotos machen • Collage • Drucken',
welcomeText: 'Zeit für ein Erinnerungsfoto!',
footerText: '👆 Display tippen! • 😊 Lächeln! • 📸 Foto schnappen!',
useFrontCamera: false,
enableLogs: true,
};
+10 -22
View File
@@ -6,17 +6,18 @@ import * as FileSystem from 'expo-file-system';
* @returns Promise<boolean> True if permissions are granted.
*/
export async function requestStoragePermission(): Promise<boolean> {
const { status, canAskAgain } = await getPermissionsAsync();
const { status, canAskAgain } = await getPermissionsAsync(true);
if (status === 'granted') {
return true;
}
if (canAskAgain) {
const { status: newStatus } = await requestPermissionsAsync();
const { status: newStatus } = await requestPermissionsAsync(true);
return newStatus === 'granted';
}
return false;
// On Android 13+, writeOnly permissions don't block MediaStore inserts
return true;
}
function getFormattedDateTime(): string {
@@ -58,9 +59,9 @@ export async function saveToGallery(localUri: string, type: 'Raw' | 'Collage', e
// 1. Create a media asset from the renamed file
const asset = await createAssetAsync(newLocalUri);
// Define album name (e.g. "Schnappix/EventName/Originale")
// Define album name
const subFolder = type === 'Raw' ? 'Originale' : 'Collagen';
const ALBUM_NAME = `Schnappix/${safeEventName}/${subFolder}`;
const ALBUM_NAME = `Schnappix - ${safeEventName} - ${subFolder}`;
try {
// 2. Check if the album already exists
@@ -68,31 +69,18 @@ export async function saveToGallery(localUri: string, type: 'Raw' | 'Collage', e
if (!album) {
// 3. If it doesn't exist, create it with our asset
await createAlbumAsync(ALBUM_NAME, asset, true);
await createAlbumAsync(ALBUM_NAME, asset, false);
console.log(`Created new album "${ALBUM_NAME}" and copied photo.`);
} else {
// 4. If it exists, add our asset to it
await addAssetsToAlbumAsync([asset], album, true);
await addAssetsToAlbumAsync([asset], album, false);
console.log(`Copied photo to existing album "${ALBUM_NAME}".`);
}
return asset.uri;
} catch (e: any) {
console.error(`Error saving asset to album ${ALBUM_NAME}, trying fallback flat album name:`, e);
// Fallback if Android blocks slashes in album names
const fallbackAlbumName = `Schnappix - ${safeEventName} - ${subFolder}`;
try {
const fallbackAlbum = await getAlbumAsync(fallbackAlbumName);
if (!fallbackAlbum) {
await createAlbumAsync(fallbackAlbumName, asset, true);
} else {
await addAssetsToAlbumAsync([asset], fallbackAlbum, true);
}
return asset.uri;
} catch (fallbackErr) {
console.error('Fallback album also failed, returning asset URI anyway:', fallbackErr);
return asset.uri;
}
console.error(`Error saving asset to album ${ALBUM_NAME}:`, e);
return asset.uri;
} finally {
// Cleanup our temp renamed file
try {