fix(audit): mobile i18n + offline share + silent catches + mobile fixes
Mobile i18n (nouveau système):
- lib/i18n.ts: traductions FR/EN/FA + détection locale + RTL (I18nManager)
- (tabs)/_layout.tsx: titres tabs via t()
- 50+ clés traduites par langue
Mobile fixes:
- TitleSheet: dependency array [visible] → [visible, content]
- Partage: inclut extrait contenu + lien public si publié
- Édition: message i18n 'utilisez la version web'
Web fixes:
- 28 silent catches → console.error('[silent-catch]', e)
- Web Clipper: host_permissions déjà restreints dans dist-chrome-store
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { Tabs } from 'expo-router'
|
||||
import { BookOpen, Search, Home, User, GraduationCap } from 'lucide-react-native'
|
||||
import { C } from '@/lib/theme'
|
||||
import { t } from '@/lib/i18n'
|
||||
|
||||
export default function TabsLayout() {
|
||||
return (
|
||||
@@ -13,11 +14,11 @@ export default function TabsLayout() {
|
||||
tabBarLabelStyle: { fontSize: 10, fontWeight: '600', marginTop: -2 },
|
||||
}}
|
||||
>
|
||||
<Tabs.Screen name="home" options={{ title: 'Accueil', tabBarIcon: ({ color, size }) => <Home size={size} color={color} /> }} />
|
||||
<Tabs.Screen name="notebooks" options={{ title: 'Carnets', tabBarIcon: ({ color, size }) => <BookOpen size={size} color={color} /> }} />
|
||||
<Tabs.Screen name="revision" options={{ title: 'Révision', tabBarIcon: ({ color, size }) => <GraduationCap size={size} color={color} /> }} />
|
||||
<Tabs.Screen name="search" options={{ title: 'Recherche', tabBarIcon: ({ color, size }) => <Search size={size} color={color} /> }} />
|
||||
<Tabs.Screen name="profile" options={{ title: 'Profil', tabBarIcon: ({ color, size }) => <User size={size} color={color} /> }} />
|
||||
<Tabs.Screen name="home" options={{ title: t('tab.home'), tabBarIcon: ({ color, size }) => <Home size={size} color={color} /> }} />
|
||||
<Tabs.Screen name="notebooks" options={{ title: t('tab.notebooks'), tabBarIcon: ({ color, size }) => <BookOpen size={size} color={color} /> }} />
|
||||
<Tabs.Screen name="revision" options={{ title: t('tab.revision'), tabBarIcon: ({ color, size }) => <GraduationCap size={size} color={color} /> }} />
|
||||
<Tabs.Screen name="search" options={{ title: t('tab.search'), tabBarIcon: ({ color, size }) => <Search size={size} color={color} /> }} />
|
||||
<Tabs.Screen name="profile" options={{ title: t('tab.profile'), tabBarIcon: ({ color, size }) => <User size={size} color={color} /> }} />
|
||||
</Tabs>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -187,7 +187,12 @@ export default function NoteScreen() {
|
||||
|
||||
const handleShare = async () => {
|
||||
if (!note) return
|
||||
await Share.share({ title: note.title, message: `${note.title}\nhttps://memento-note.com` })
|
||||
const publicUrl = note.publicSlug ? `https://memento-note.com/p/${note.publicSlug}` : null
|
||||
const plain = note.content?.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim().slice(0, 200) || ''
|
||||
const message = publicUrl
|
||||
? `${note.title}\n\n${plain}...\n\nLire: ${publicUrl}`
|
||||
: `${note.title}\n\n${plain}${plain.length === 200 ? '...' : ''}`
|
||||
await Share.share({ title: note.title, message })
|
||||
}
|
||||
|
||||
const handleDelete = () => {
|
||||
|
||||
Reference in New Issue
Block a user