diff --git a/src/screens/EmailListScreen.tsx b/src/screens/EmailListScreen.tsx index 1058903e..446f0399 100644 --- a/src/screens/EmailListScreen.tsx +++ b/src/screens/EmailListScreen.tsx @@ -388,7 +388,7 @@ export default function EmailListScreen({ const resolvedTheme = useResolvedTheme(); // The undo bar floats over the list's bottom right on a phone (on a split // layout it sits over the reading pane instead). - const { isSplit } = useLayout(); + const { isSplit, shortHeight } = useLayout(); const listUndo = useEmailStore((s) => s.pendingUndo != null); const sendUndo = useSendUndoStore((s) => s.pending != null); const undoBarUp = !isSplit && (listUndo || sendUndo); @@ -1066,6 +1066,90 @@ export default function EmailListScreen({ } }, [mailboxes, currentMailboxId, selectMailbox]); + const renderSearchBar = (inHeader: boolean) => ( + + + {allSelected ? ( + + ) : selectionMode ? ( + + + + ) : ( + + )} + + + + setSearchFocused(true)} + // Delay so a tap on a recent-search row lands before the list hides. + onBlur={() => { setTimeout(() => setSearchFocused(false), 150); }} + onSubmitEditing={() => submitSearch(searchInput)} + autoCapitalize="none" + autoCorrect={false} + returnKeyType="search" + /> + {searchInput.length > 0 && ( + { setSearchInput(''); setSearchQuery(''); }} + hitSlop={8} + style={styles.searchClearButton} + accessibilityRole="button" + accessibilityLabel={t('contacts.clear_search', 'Clear search')} + > + + + )} + + setSortAscending(!sortAscending)} + accessibilityRole="button" + accessibilityLabel={sortAscending + ? t('settings.appearance.message_list_order.direction.oldest_first', 'Oldest first') + : t('settings.appearance.message_list_order.direction.newest_first', 'Newest first')} + accessibilityHint={t('email_list.sort_toggle_hint', 'Reverses the mail sort order')} + > + {sortAscending ? ( + + ) : ( + + )} + + 0 && styles.filterButtonActive]} + onPress={() => setFilterMenuOpen(true)} + accessibilityRole="button" + accessibilityLabel={t('advanced_search.advanced_filters_tooltip', 'Advanced search filters')} + accessibilityValue={activeFilterCount > 0 ? { text: String(activeFilterCount) } : undefined} + > + 0 ? c.primary : c.textMuted} /> + {activeFilterCount > 0 && ( + + {activeFilterCount} + + )} + + + ); + return ( {/* Header */} @@ -1176,10 +1260,12 @@ export default function EmailListScreen({ )} - + {headerTitle} - + {/* A phone in landscape has room for a few rows only: the search + shares the header row instead of taking its own. */} + {shortHeight ? renderSearchBar(true) : } { void handleImport(); }} style={styles.headerButton} @@ -1203,88 +1289,8 @@ export default function EmailListScreen({ )} - {/* Search bar (always visible) */} - - - {allSelected ? ( - - ) : selectionMode ? ( - - - - ) : ( - - )} - - - - setSearchFocused(true)} - // Delay so a tap on a recent-search row lands before the list hides. - onBlur={() => { setTimeout(() => setSearchFocused(false), 150); }} - onSubmitEditing={() => submitSearch(searchInput)} - autoCapitalize="none" - autoCorrect={false} - returnKeyType="search" - /> - {searchInput.length > 0 && ( - { setSearchInput(''); setSearchQuery(''); }} - hitSlop={8} - style={styles.searchClearButton} - accessibilityRole="button" - accessibilityLabel={t('contacts.clear_search', 'Clear search')} - > - - - )} - - setSortAscending(!sortAscending)} - accessibilityRole="button" - accessibilityLabel={sortAscending - ? t('settings.appearance.message_list_order.direction.oldest_first', 'Oldest first') - : t('settings.appearance.message_list_order.direction.newest_first', 'Newest first')} - accessibilityHint={t('email_list.sort_toggle_hint', 'Reverses the mail sort order')} - > - {sortAscending ? ( - - ) : ( - - )} - - 0 && styles.filterButtonActive]} - onPress={() => setFilterMenuOpen(true)} - accessibilityRole="button" - accessibilityLabel={t('advanced_search.advanced_filters_tooltip', 'Advanced search filters')} - accessibilityValue={activeFilterCount > 0 ? { text: String(activeFilterCount) } : undefined} - > - 0 ? c.primary : c.textMuted} /> - {activeFilterCount > 0 && ( - - {activeFilterCount} - - )} - - + {/* Search bar (always visible; inside the header in a short window) */} + {!shortHeight && renderSearchBar(false)} {searchFocused && ((!searchInput.trim() && recentSearches.length > 0) || contactSuggestions.length > 0) && ( @@ -1967,6 +1973,8 @@ function makeStyles(c: ThemePalette) { marginVertical: spacing.sm, gap: spacing.sm, }, + searchBarInHeader: { flex: 1, marginHorizontal: 0, marginVertical: 0 }, + headerTitleShort: { flexShrink: 1, maxWidth: 180 }, checkboxButton: { width: componentSizes.buttonMd, height: componentSizes.buttonMd, alignItems: 'center', justifyContent: 'center',