import { useState } from 'react'; import { LayoutAnimation, Platform, ScrollView, TouchableOpacity, Text, UIManager, View, } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import { useTranslation } from 'react-i18next'; import { useMailResults, type MailBlockedItem } from '../../hooks/useMailResults'; import { useColors } from '../../lib/theme'; if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental) { UIManager.setLayoutAnimationEnabledExperimental(true); } type Props = { expanded: boolean; onToggle: () => void; providers?: string[]; }; function formatDate(iso: string, t: (k: string) => string): string { const diff = Date.now() - new Date(iso).getTime(); const mins = Math.floor(diff / 60_000); if (mins < 2) return t('mail.account_just_now'); if (mins < 60) return `${mins} min`; const hours = Math.floor(mins / 60); if (hours < 24) return `${hours}h`; return `${Math.floor(hours / 24)}d`; } function domainFromEmail(email: string): string { return email.split('@')[1] ?? email; } function providerDisplayName(provider: string): string { const map: Record = { gmail: 'Gmail', icloud: 'iCloud', outlook: 'Outlook', yahoo: 'Yahoo', gmx: 'GMX', other: 'Andere', }; return map[provider.toLowerCase()] ?? provider; } export function MailActivityLog({ expanded, onToggle, providers = [] }: Props) { const { t } = useTranslation(); const colors = useColors(); const [activeProvider, setActiveProvider] = useState('all'); const { results, total, loading, refresh } = useMailResults(expanded, activeProvider); const filterOptions = ['all', ...providers]; function handleToggle() { LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); onToggle(); } function handleProviderFilter(p: string) { setActiveProvider(p); } return ( {t('mail.activity_log_title')} {t('mail.activity_log_subtitle')} {expanded && ( {/* Provider filter chips */} {filterOptions.length > 1 && ( {filterOptions.map((p) => { const active = activeProvider === p; return ( handleProviderFilter(p)} style={{ paddingHorizontal: 12, paddingVertical: 5, borderRadius: 999, backgroundColor: active ? '#007AFF' : colors.surfaceElevated, borderWidth: active ? 0 : 1, borderColor: colors.border, }} > {p === 'all' ? t('mail.filter.all') : providerDisplayName(p)} ); })} )} {loading && results.length === 0 ? ( {t('mail.loading')} ) : results.length === 0 ? ( {t('mail.activity_log_empty')} ) : ( <> {results.slice(0, 10).map((item) => ( ))} {total > 10 ? t('mail.activity_log_more', { count: total - 10 }) : t('mail.activity_log_count', { count: total })} )} )} ); } function ActivityItem({ item, t, colors, }: { item: MailBlockedItem; t: (k: string, opts?: any) => string; colors: ReturnType; }) { const accountLabel = item.connection_title ?? ( item.sender_email ? domainFromEmail(item.sender_email) : null ); return ( {item.subject || t('mail.activity_no_subject')} {accountLabel && ( {accountLabel} )} {item.sender_name || item.sender_email} {formatDate(item.received_at, t)} ); }