restore(mobile): restore mobile/ directory to pre-d2217531 state

Restored mobile/ from d22175310a711e7ebdd8062ae29a54f0136dc3f6^
(parent commit d94e9ca4bc).

Commit d22175310a (google-labs-jules[bot], 2026-03-23T14:45:22Z) introduced
an SSRF security fix for IMAP connections but unintentionally deleted or
truncated a large number of files across the repository, including 24 files
under mobile/.

This commit targets only the mobile/ directory and restores the following
files to their pre-d2217531 state:

- mobile/README.md
- mobile/app.json
- mobile/app/(tabs)/_layout.tsx
- mobile/app/(tabs)/file-detail.tsx  (re-added)
- mobile/app/+not-found.tsx          (re-added)
- mobile/app/_layout.tsx
- mobile/eslint.config.js            (re-added)
- mobile/package-lock.json
- mobile/package.json
- mobile/src/context/ShareContext.tsx
- mobile/src/i18n/de.json            (re-added)
- mobile/src/i18n/en.json            (re-added)
- mobile/src/i18n/es.json            (re-added)
- mobile/src/i18n/fr.json            (re-added)
- mobile/src/i18n/index.ts           (re-added)
- mobile/src/i18n/it.json            (re-added)
- mobile/src/screens/FileDetailScreen.tsx (re-added)
- mobile/src/screens/FilesScreen.tsx
- mobile/src/screens/LoginScreen.tsx
- mobile/src/screens/ProfileScreen.tsx
- mobile/src/screens/UploadScreen.tsx
- mobile/src/screens/WelcomeScreen.tsx
- mobile/src/services/api.ts
- mobile/src/utils/mimeTypes.ts      (re-added)
- mobile/src/utils/normalizeUri.ts   (re-added)

Security fixes introduced by d2217531 that are unrelated to mobile/
(IMAP SSRF fix in app/utils/network.py and app/tasks/imap_tasks.py)
are preserved — this restore targets only files under mobile/.
This commit is contained in:
copilot-swe-agent[bot]
2026-03-24 12:12:05 +00:00
parent aca12858c1
commit 2f3c22000c
25 changed files with 2354 additions and 646 deletions
+81 -29
View File
@@ -6,6 +6,7 @@
*/
import { useRouter } from "expo-router";
import * as Linking from "expo-linking";
import React from "react";
import {
Image,
@@ -16,27 +17,31 @@ import {
View,
} from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
const FEATURES: { icon: string; title: string; description: string }[] = [
{
icon: "🔍",
title: "OCR & Text Extraction",
description: "Convert scanned PDFs and images into fully searchable text automatically.",
},
{
icon: "🤖",
title: "AI Metadata Extraction",
description: "AI classifies documents and pulls out key fields like dates, amounts, and subjects.",
},
{
icon: "☁️",
title: "Multi-Cloud Storage",
description: "Route processed files to Dropbox, Google Drive, OneDrive, S3, Nextcloud, and more.",
},
];
import { useLocale, t } from "../i18n";
export default function WelcomeScreen() {
const router = useRouter();
// Subscribe to language changes so translated strings re-render.
useLocale();
const features = [
{
icon: "🔍",
title: t("welcome.feature_ocr_title"),
description: t("welcome.feature_ocr_desc"),
},
{
icon: "🤖",
title: t("welcome.feature_ai_title"),
description: t("welcome.feature_ai_desc"),
},
{
icon: "☁️",
title: t("welcome.feature_cloud_title"),
description: t("welcome.feature_cloud_desc"),
},
];
return (
<SafeAreaView style={styles.safe}>
<ScrollView
@@ -54,16 +59,13 @@ export default function WelcomeScreen() {
/>
</View>
<Text style={styles.appName}>DocuElevate</Text>
<Text style={styles.tagline}>Intelligent Document Processing</Text>
<Text style={styles.heroDescription}>
Ingest documents, run OCR, extract metadata with AI, and route files
to your cloud storage — all in one seamless pipeline.
</Text>
<Text style={styles.tagline}>{t("welcome.tagline")}</Text>
<Text style={styles.heroDescription}>{t("welcome.description")}</Text>
</View>
{/* Feature highlights */}
<View style={styles.features}>
{FEATURES.map((feature) => (
{features.map((feature) => (
<View key={feature.title} style={styles.featureRow}>
<Text style={styles.featureIcon} aria-hidden={true}>{feature.icon}</Text>
<View style={styles.featureText}>
@@ -79,14 +81,42 @@ export default function WelcomeScreen() {
style={({ pressed }) => [styles.button, pressed && styles.buttonPressed]}
onPress={() => router.push("/(auth)/login")}
accessibilityRole="button"
accessibilityLabel="Get started — connect to your DocuElevate server"
accessibilityLabel={t("welcome.get_started")}
>
<Text style={styles.buttonText}>Get Started</Text>
<Text style={styles.buttonText}>{t("welcome.get_started")}</Text>
</Pressable>
<Text style={styles.hint}>
Connect to your self-hosted or cloud DocuElevate server.
</Text>
<Text style={styles.hint}>{t("welcome.hint")}</Text>
{/* Legal links – accessible pre-login for GDPR / Apple compliance */}
<View style={styles.legalLinks}>
<Pressable
onPress={() => Linking.openURL("https://app.docuelevate.org/privacy")}
accessibilityRole="link"
accessibilityLabel={t("legal.privacy_policy")}
style={styles.legalLinkButton}
>
<Text style={styles.legalLinkText}>{t("legal.privacy_policy")}</Text>
</Pressable>
<Text style={styles.legalSeparator}>·</Text>
<Pressable
onPress={() => Linking.openURL("https://app.docuelevate.org/terms")}
accessibilityRole="link"
accessibilityLabel={t("legal.terms")}
style={styles.legalLinkButton}
>
<Text style={styles.legalLinkText}>{t("legal.terms")}</Text>
</Pressable>
<Text style={styles.legalSeparator}>·</Text>
<Pressable
onPress={() => Linking.openURL("https://app.docuelevate.org/imprint")}
accessibilityRole="link"
accessibilityLabel={t("legal.imprint")}
style={styles.legalLinkButton}
>
<Text style={styles.legalLinkText}>{t("legal.imprint")}</Text>
</Pressable>
</View>
</ScrollView>
</SafeAreaView>
);
@@ -206,4 +236,26 @@ const styles = StyleSheet.create({
color: "rgba(255,255,255,0.55)",
textAlign: "center",
},
legalLinks: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
marginTop: 20,
flexWrap: "wrap",
},
legalLinkButton: {
minHeight: 44,
justifyContent: "center",
paddingHorizontal: 4,
},
legalLinkText: {
fontSize: 12,
color: "rgba(255,255,255,0.65)",
textDecorationLine: "underline",
},
legalSeparator: {
fontSize: 12,
color: "rgba(255,255,255,0.45)",
marginHorizontal: 4,
},
});