Tweak email display (#771)

This commit is contained in:
Leendert de Borst
2025-05-06 23:09:03 +02:00
parent 8d6b04448f
commit e24b270610
5 changed files with 53 additions and 7 deletions

View File

@@ -1,5 +1,5 @@
import React, { useEffect, useState, useCallback } from 'react';
import { StyleSheet, View, TouchableOpacity, ActivityIndicator, Alert, Share, useColorScheme, TextInput } from 'react-native';
import { StyleSheet, View, TouchableOpacity, ActivityIndicator, Alert, Share, useColorScheme, TextInput, Linking } from 'react-native';
import { useLocalSearchParams, useRouter, useNavigation, Stack } from 'expo-router';
import { WebView } from 'react-native-webview';
import * as FileSystem from 'expo-file-system';
@@ -447,9 +447,8 @@ export default function EmailDetailsScreen() : React.ReactNode {
scrollEnabled={true}
onNavigationStateChange={(event) => {
if (event.url !== 'about:blank') {
Share.share({
url: event.url,
});
// Open the URL in the browser
Linking.openURL(event.url);
}
}}
/>

View File

@@ -164,7 +164,7 @@ export default function EmailsScreen() : React.ReactNode {
if (isLoading) {
return (
<View style={styles.loadingContainer}>
<SkeletonLoader count={4} height={90} parts={3} />
<SkeletonLoader count={3} height={120} parts={4} />
</View>
);
}

View File

@@ -1,9 +1,13 @@
import { StyleSheet, View, TouchableOpacity } from 'react-native';
import { router } from 'expo-router';
import { useEffect, useState } from 'react';
import { ThemedText } from '@/components/themed/ThemedText';
import { useColors } from '@/hooks/useColorScheme';
import { MailboxEmail } from '@/utils/types/webapi/MailboxEmail';
import { useDb } from '@/context/DbContext';
import { Credential } from '@/utils/types/Credential';
import { IconSymbol } from '@/components/ui/IconSymbol';
type EmailCardProps = {
email: MailboxEmail;
@@ -14,6 +18,28 @@ type EmailCardProps = {
*/
export function EmailCard({ email }: EmailCardProps) : React.ReactNode {
const colors = useColors();
const dbContext = useDb();
const [associatedCredential, setAssociatedCredential] = useState<Credential | null>(null);
/**
* Load the associated credential for this email.
*/
useEffect(() => {
/**
* Load the credential associated with the email's recipient address.
*/
const loadCredential = async (): Promise<void> => {
if (!dbContext?.sqliteClient || !email.toLocal || !email.toDomain) {
return;
}
const emailAddress = `${email.toLocal}@${email.toDomain}`;
const credential = await dbContext.sqliteClient.getCredentialByEmail(emailAddress);
setAssociatedCredential(credential);
};
loadCredential();
}, [dbContext?.sqliteClient, email.toLocal, email.toDomain]);
/**
* Format the email date.
@@ -79,6 +105,18 @@ export function EmailCard({ email }: EmailCardProps) : React.ReactNode {
fontWeight: 'bold',
marginRight: 8,
},
serviceContainer: {
alignItems: 'center',
flexDirection: 'row',
marginTop: 4,
},
serviceIcon: {
marginRight: 4,
},
serviceName: {
color: colors.primary,
fontSize: 12,
},
});
return (
@@ -98,6 +136,14 @@ export function EmailCard({ email }: EmailCardProps) : React.ReactNode {
<ThemedText style={styles.emailPreview} numberOfLines={2}>
{email.messagePreview}
</ThemedText>
{associatedCredential && (
<View style={styles.serviceContainer}>
<IconSymbol size={14} name="key.fill" color={colors.primary} style={styles.serviceIcon} />
<ThemedText style={styles.serviceName}>
{associatedCredential.ServiceName}
</ThemedText>
</View>
)}
</TouchableOpacity>
);
}

View File

@@ -15,7 +15,8 @@ export const LoginCredentials: React.FC<LoginCredentialsProps> = ({ credential }
const username = credential.Username?.trim();
const password = credential.Password?.trim();
const hasLoginCredentials = email ?? username ?? password;
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const hasLoginCredentials = email || username || password;
if (!hasLoginCredentials) {
return null;

View File

@@ -7,7 +7,7 @@ export const Colors = {
light: {
text: '#11181C',
textMuted: '#4b5563',
background: '#f3f4f6',
background: '#f3f2f7',
accentBackground: '#fff',
accentBorder: '#d1d5db',
errorBackground: '#f8d7da',