From e24b270610e6a446e865ad2035b59f2e5ceea9af Mon Sep 17 00:00:00 2001 From: Leendert de Borst Date: Tue, 6 May 2025 23:09:03 +0200 Subject: [PATCH] Tweak email display (#771) --- apps/mobile-app/app/(tabs)/emails/[id].tsx | 7 ++- apps/mobile-app/app/(tabs)/emails/index.tsx | 2 +- apps/mobile-app/components/EmailCard.tsx | 46 +++++++++++++++++++ .../credentials/details/LoginCredentials.tsx | 3 +- apps/mobile-app/constants/Colors.ts | 2 +- 5 files changed, 53 insertions(+), 7 deletions(-) diff --git a/apps/mobile-app/app/(tabs)/emails/[id].tsx b/apps/mobile-app/app/(tabs)/emails/[id].tsx index e1340f1db..9d2950274 100644 --- a/apps/mobile-app/app/(tabs)/emails/[id].tsx +++ b/apps/mobile-app/app/(tabs)/emails/[id].tsx @@ -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); } }} /> diff --git a/apps/mobile-app/app/(tabs)/emails/index.tsx b/apps/mobile-app/app/(tabs)/emails/index.tsx index c1e688054..84c8dfc45 100644 --- a/apps/mobile-app/app/(tabs)/emails/index.tsx +++ b/apps/mobile-app/app/(tabs)/emails/index.tsx @@ -164,7 +164,7 @@ export default function EmailsScreen() : React.ReactNode { if (isLoading) { return ( - + ); } diff --git a/apps/mobile-app/components/EmailCard.tsx b/apps/mobile-app/components/EmailCard.tsx index 0fdd36933..506f2c317 100644 --- a/apps/mobile-app/components/EmailCard.tsx +++ b/apps/mobile-app/components/EmailCard.tsx @@ -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(null); + + /** + * Load the associated credential for this email. + */ + useEffect(() => { + /** + * Load the credential associated with the email's recipient address. + */ + const loadCredential = async (): Promise => { + 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 { {email.messagePreview} + {associatedCredential && ( + + + + {associatedCredential.ServiceName} + + + )} ); } \ No newline at end of file diff --git a/apps/mobile-app/components/credentials/details/LoginCredentials.tsx b/apps/mobile-app/components/credentials/details/LoginCredentials.tsx index 8c8b05d45..c2da79e1f 100644 --- a/apps/mobile-app/components/credentials/details/LoginCredentials.tsx +++ b/apps/mobile-app/components/credentials/details/LoginCredentials.tsx @@ -15,7 +15,8 @@ export const LoginCredentials: React.FC = ({ 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; diff --git a/apps/mobile-app/constants/Colors.ts b/apps/mobile-app/constants/Colors.ts index 570cc90a1..c5c04478d 100644 --- a/apps/mobile-app/constants/Colors.ts +++ b/apps/mobile-app/constants/Colors.ts @@ -7,7 +7,7 @@ export const Colors = { light: { text: '#11181C', textMuted: '#4b5563', - background: '#f3f4f6', + background: '#f3f2f7', accentBackground: '#fff', accentBorder: '#d1d5db', errorBackground: '#f8d7da',