fix: allow adding contacts from mail recipient popover on mobile #306
This commit is contained in:
@@ -52,6 +52,8 @@ interface ContactFormProps {
|
||||
addressBooks?: AddressBook[];
|
||||
allKeywords?: string[];
|
||||
defaultAddressBookId?: string;
|
||||
/** Prefills the create form (ignored when `contact` is set). */
|
||||
prefill?: { email?: string; name?: string };
|
||||
onSave: (data: Partial<ContactCard>) => Promise<void>;
|
||||
onCancel: () => void;
|
||||
}
|
||||
@@ -145,10 +147,22 @@ function Select({ value, onChange, children, className }: {
|
||||
);
|
||||
}
|
||||
|
||||
export function ContactForm({ contact, addressBooks, allKeywords, defaultAddressBookId, onSave, onCancel }: ContactFormProps) {
|
||||
export function ContactForm({ contact, addressBooks, allKeywords, defaultAddressBookId, prefill, onSave, onCancel }: ContactFormProps) {
|
||||
const t = useTranslations("contacts.form");
|
||||
const isEditing = !!contact;
|
||||
|
||||
// Split a free-form display name into given/surname for prefill.
|
||||
const prefillGivenName = (() => {
|
||||
if (contact || !prefill?.name) return "";
|
||||
const parts = prefill.name.trim().split(/\s+/);
|
||||
return parts[0] || "";
|
||||
})();
|
||||
const prefillSurname = (() => {
|
||||
if (contact || !prefill?.name) return "";
|
||||
const parts = prefill.name.trim().split(/\s+/);
|
||||
return parts.slice(1).join(" ");
|
||||
})();
|
||||
|
||||
// Accept JSContact-standard kinds (RFC 9553) and legacy vCard-style aliases.
|
||||
const findComponent = (...kinds: string[]) =>
|
||||
contact?.name?.components?.find(c => kinds.includes(c.kind))?.value || "";
|
||||
@@ -215,9 +229,9 @@ export function ContactForm({ contact, addressBooks, allKeywords, defaultAddress
|
||||
}
|
||||
|
||||
const [prefix, setPrefix] = useState(findComponent("title", "prefix"));
|
||||
const [givenName, setGivenName] = useState(findComponent("given"));
|
||||
const [givenName, setGivenName] = useState(findComponent("given") || prefillGivenName);
|
||||
const [additionalName, setAdditionalName] = useState(findComponent("given2", "additional", "middle"));
|
||||
const [surname, setSurname] = useState(findComponent("surname"));
|
||||
const [surname, setSurname] = useState(findComponent("surname") || prefillSurname);
|
||||
const [suffix, setSuffix] = useState(findComponent("generation", "suffix"));
|
||||
|
||||
const [nickname, setNickname] = useState(
|
||||
@@ -231,7 +245,7 @@ export function ContactForm({ contact, addressBooks, allKeywords, defaultAddress
|
||||
context: e.contexts?.work ? "work" : e.contexts?.private ? "private" : "",
|
||||
}));
|
||||
}
|
||||
return [{ address: "", context: "" }];
|
||||
return [{ address: prefill?.email || "", context: "" }];
|
||||
});
|
||||
|
||||
const [phones, setPhones] = useState<PhoneEntry[]>(() => {
|
||||
|
||||
@@ -65,6 +65,7 @@ import {
|
||||
PenSquare,
|
||||
} from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useRouter } from "@/i18n/navigation";
|
||||
import type { Attachment as PostalMimeAttachment } from 'postal-mime';
|
||||
import { useSettingsStore, KEYWORD_PALETTE } from "@/stores/settings-store";
|
||||
import { useUIStore } from "@/stores/ui-store";
|
||||
@@ -1137,9 +1138,34 @@ export function EmailViewer({
|
||||
const [contactSidebarEmail, setContactSidebarEmail] = useState<string | null>(null);
|
||||
const contacts = useContactStore((s) => s.contacts);
|
||||
const { isMobile: isMobileDevice } = useDeviceDetection();
|
||||
const router = useRouter();
|
||||
|
||||
const handleViewContactSidebar = (contact: ContactCard | null, recipientEmail: string) => {
|
||||
if (isMobileDevice) return; // no sidebar on mobile
|
||||
if (isMobileDevice) {
|
||||
// No room for a sidebar on mobile — send the user to the contacts page
|
||||
// with params describing what to show. The `from=email` flag turns the
|
||||
// page's mobile back button into a router.back() that returns here.
|
||||
const allRecipients = [
|
||||
...(email?.from || []),
|
||||
...(email?.to || []),
|
||||
...(email?.cc || []),
|
||||
...(email?.bcc || []),
|
||||
...(email?.replyTo || []),
|
||||
];
|
||||
const recipientName = allRecipients.find(
|
||||
(r) => r.email.toLowerCase() === recipientEmail.toLowerCase()
|
||||
)?.name;
|
||||
const params = new URLSearchParams();
|
||||
if (contact) {
|
||||
params.set('contactId', contact.id);
|
||||
} else {
|
||||
params.set('addEmail', recipientEmail);
|
||||
if (recipientName) params.set('addName', recipientName);
|
||||
}
|
||||
params.set('from', 'email');
|
||||
router.push(`/contacts?${params.toString()}`);
|
||||
return;
|
||||
}
|
||||
setContactSidebarEmail(recipientEmail);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user