mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-03 16:07:32 +00:00
fix: keep sheet and dialog fields and buttons above the keyboard
This commit is contained in:
@@ -14,6 +14,7 @@ import { isTrustedSendersSyncOn } from '../../lib/trusted-senders';
|
||||
import { removeTrustedSenderWithUndo } from '../../lib/settings-undo';
|
||||
import { useLocaleStore } from '../../stores/locale-store';
|
||||
import { MODAL_ORIENTATIONS } from '../../lib/modal-orientations';
|
||||
import { useSheetBottomInset } from '../../lib/sheet-bottom-inset';
|
||||
import { ToastHost } from '../ToastHost';
|
||||
|
||||
interface TrustedRow {
|
||||
@@ -48,6 +49,8 @@ export function ContentSendersSettings() {
|
||||
const removeFromTrustedSendersBook = useContactsStore((s) => s.removeFromTrustedSendersBook);
|
||||
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
// The card centres above the keyboard while an address is typed in.
|
||||
const bottomInset = useSheetBottomInset(modalOpen);
|
||||
const [newSender, setNewSender] = useState('');
|
||||
const [busy, setBusy] = useState<string | null>(null);
|
||||
|
||||
@@ -197,7 +200,7 @@ export function ContentSendersSettings() {
|
||||
animationType="fade"
|
||||
onRequestClose={() => setModalOpen(false)}
|
||||
>
|
||||
<Pressable accessible={false} style={styles.modalBackdrop} onPress={() => setModalOpen(false)}>
|
||||
<Pressable accessible={false} style={[styles.modalBackdrop, { paddingBottom: bottomInset }]} onPress={() => setModalOpen(false)}>
|
||||
<Pressable accessible={false} style={styles.modalCard} onPress={() => {}}>
|
||||
<View style={styles.modalHeader}>
|
||||
<Text style={styles.modalTitle}>{t('settings.email_behavior.trusted_senders.modal_title', 'Trusted Senders')}</Text>
|
||||
|
||||
@@ -19,6 +19,7 @@ import { spacing, radius, typography, type ThemePalette } from '../../theme/toke
|
||||
import { useColors } from '../../theme/colors';
|
||||
import { useLocaleStore } from '../../stores/locale-store';
|
||||
import { MODAL_ORIENTATIONS } from '../../lib/modal-orientations';
|
||||
import { useModalKeyboardPadding } from '../../lib/sheet-bottom-inset';
|
||||
import { findPrincipalByEmail } from '../../api/delegation';
|
||||
import type { Principal } from '../../api/types';
|
||||
import type { PrincipalListing } from '../../api/files';
|
||||
@@ -74,6 +75,8 @@ export function DelegateDialog({
|
||||
const c = useColors();
|
||||
const styles = useMemo(() => makeStyles(c), [c]);
|
||||
const t = useLocaleStore((s) => s.t);
|
||||
// The Android dialog doesn't shrink for the keyboard; the body ends above it.
|
||||
const keyboardPadding = useModalKeyboardPadding();
|
||||
const changing = !!initial;
|
||||
|
||||
const [principal, setPrincipal] = useState<Principal | null>(initial?.principal ?? null);
|
||||
@@ -154,7 +157,7 @@ export function DelegateDialog({
|
||||
return (
|
||||
<SafeAreaModal supportedOrientations={MODAL_ORIENTATIONS} visible animationType="slide" onRequestClose={close}>
|
||||
<SafeAreaView style={styles.screen} edges={['top', 'bottom', 'left', 'right']}>
|
||||
<KeyboardAvoidingView style={styles.screen} behavior={Platform.OS === 'ios' ? 'padding' : undefined}>
|
||||
<KeyboardAvoidingView style={[styles.screen, { paddingBottom: keyboardPadding }]} behavior={Platform.OS === 'ios' ? 'padding' : undefined}>
|
||||
<View style={styles.header}>
|
||||
<Text style={styles.title} numberOfLines={1} accessibilityRole="header">
|
||||
{changing && principal
|
||||
|
||||
@@ -69,7 +69,6 @@ function pathOf(all: Mailbox[], mb: Mailbox, t: (k: string, f?: string) => strin
|
||||
export function FolderSettings() {
|
||||
// Centred on a wide window, clear of side insets in landscape.
|
||||
const sheetInsets = useSheetInsets();
|
||||
const bottomInset = useSheetBottomInset();
|
||||
const c = useColors();
|
||||
const styles = React.useMemo(() => makeStyles(c), [c]);
|
||||
const t = useLocaleStore((s) => s.t);
|
||||
@@ -78,6 +77,9 @@ export function FolderSettings() {
|
||||
const fetchMailboxes = useEmailStore((s) => s.fetchMailboxes);
|
||||
|
||||
const [editor, setEditor] = useState<Editor | null>(null);
|
||||
// Save and Cancel above the taskbar, and above the keyboard while the
|
||||
// name is typed in.
|
||||
const bottomInset = useSheetBottomInset(!!editor);
|
||||
const [draftName, setDraftName] = useState('');
|
||||
const [draftParent, setDraftParent] = useState<string>(NO_PARENT);
|
||||
const [draftAccount, setDraftAccount] = useState<string>(OWN_ACCOUNT);
|
||||
|
||||
@@ -99,7 +99,6 @@ function parseAddressList(value: string): { list: EmailAddress[]; invalid: strin
|
||||
export function IdentitySettings() {
|
||||
// Centred on a wide window, clear of side insets in landscape.
|
||||
const sheetInsets = useSheetInsets();
|
||||
const bottomInset = useSheetBottomInset();
|
||||
const c = useColors();
|
||||
const styles = React.useMemo(() => makeStyles(c), [c]);
|
||||
const identities = useSettingsStore((s) => s.identities);
|
||||
@@ -113,6 +112,8 @@ export function IdentitySettings() {
|
||||
const preferredId = accountId ? preferredIdentityIds[accountId] : undefined;
|
||||
|
||||
const [editing, setEditing] = useState<DraftIdentity | null>(null);
|
||||
// Save above the taskbar, and above the keyboard while a field is typed in.
|
||||
const bottomInset = useSheetBottomInset(!!editing);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [deletingId, setDeletingId] = useState<string | null>(null);
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ import { useSheetBottomInset } from '../../lib/sheet-bottom-inset';
|
||||
export function TemplateSettings() {
|
||||
// Centred on a wide window, clear of side insets in landscape.
|
||||
const sheetInsets = useSheetInsets();
|
||||
const bottomInset = useSheetBottomInset();
|
||||
const c = useColors();
|
||||
const styles = React.useMemo(() => makeStyles(c), [c]);
|
||||
const tr = useLocaleStore((s) => s.t);
|
||||
@@ -41,6 +40,8 @@ export function TemplateSettings() {
|
||||
|
||||
const [editing, setEditing] = useState<EmailTemplate | null>(null);
|
||||
const [importVisible, setImportVisible] = useState(false);
|
||||
// Save above the taskbar, and above the keyboard while a field is typed in.
|
||||
const bottomInset = useSheetBottomInset(!!editing || importVisible);
|
||||
const [importText, setImportText] = useState('');
|
||||
const [draftName, setDraftName] = useState('');
|
||||
const [draftSubject, setDraftSubject] = useState('');
|
||||
|
||||
Reference in New Issue
Block a user