fix: sync identity stores and append signatures to outgoing emails (#15)
- Add syncIdentities() to auth store to propagate identity changes from identity store, fixing stale data that caused save failures and duplicates - Call syncIdentities() after every create, update, and delete in the identity manager modal - Switch email composer to read identities from identity store for consistency with the rest of the app - Append identity text signature (with RFC 3676 separator) to email body when sending from the composer and quick reply paths - Add tests for syncIdentities and signature appending logic
This commit is contained in:
@@ -10,6 +10,7 @@ import { cn, formatFileSize } from "@/lib/utils";
|
||||
import { debug } from "@/lib/debug";
|
||||
import { toast } from "@/stores/toast-store";
|
||||
import { useAuthStore } from "@/stores/auth-store";
|
||||
import { useIdentityStore } from "@/stores/identity-store";
|
||||
import { useContactStore } from "@/stores/contact-store";
|
||||
import { useTemplateStore } from "@/stores/template-store";
|
||||
import { SubAddressHelper } from "@/components/identity/sub-address-helper";
|
||||
@@ -159,7 +160,9 @@ export function EmailComposer({
|
||||
restoreFocus: true,
|
||||
});
|
||||
|
||||
const { client, identities, primaryIdentity } = useAuthStore();
|
||||
const { client } = useAuthStore();
|
||||
const identities = useIdentityStore((s) => s.identities);
|
||||
const primaryIdentity = identities[0] ?? null;
|
||||
const getAutocomplete = useContactStore((s) => s.getAutocomplete);
|
||||
const addTemplate = useTemplateStore((s) => s.addTemplate);
|
||||
|
||||
@@ -549,13 +552,19 @@ export function EmailComposer({
|
||||
: currentIdentity.email
|
||||
: undefined;
|
||||
|
||||
// Append signature from the selected identity
|
||||
let finalBody = body;
|
||||
if (currentIdentity?.textSignature) {
|
||||
finalBody = body + '\n\n-- \n' + currentIdentity.textSignature;
|
||||
}
|
||||
|
||||
try {
|
||||
await onSend?.({
|
||||
to: toAddresses,
|
||||
cc: ccAddresses,
|
||||
bcc: bccAddresses,
|
||||
subject,
|
||||
body,
|
||||
body: finalBody,
|
||||
draftId: finalDraftId || undefined,
|
||||
fromEmail,
|
||||
fromName: currentIdentity?.name || undefined,
|
||||
|
||||
@@ -9,6 +9,11 @@ import { ConfirmDialog } from '@/components/ui/confirm-dialog';
|
||||
import { IdentityForm } from './identity-form';
|
||||
import { useIdentityStore } from '@/stores/identity-store';
|
||||
import { useAuthStore } from '@/stores/auth-store';
|
||||
|
||||
function useSyncIdentities() {
|
||||
const syncIdentities = useAuthStore((state) => state.syncIdentities);
|
||||
return syncIdentities;
|
||||
}
|
||||
import type { Identity, EmailAddress } from '@/lib/jmap/types';
|
||||
import { toast } from '@/stores/toast-store';
|
||||
import { useFocusTrap } from '@/hooks/use-focus-trap';
|
||||
@@ -34,6 +39,7 @@ export function IdentityManagerModal({ isOpen, onClose }: IdentityManagerModalPr
|
||||
|
||||
const client = useAuthStore((state) => state.client);
|
||||
const { identities, addIdentity, updateIdentityLocal, removeIdentity } = useIdentityStore();
|
||||
const syncIdentities = useSyncIdentities();
|
||||
|
||||
const [editingId, setEditingId] = useState<string | null>(null);
|
||||
const [isCreating, setIsCreating] = useState(false);
|
||||
@@ -82,6 +88,7 @@ export function IdentityManagerModal({ isOpen, onClose }: IdentityManagerModalPr
|
||||
);
|
||||
|
||||
addIdentity(newIdentity);
|
||||
syncIdentities();
|
||||
setIsCreating(false);
|
||||
toast.success(tNotif('identity_created'));
|
||||
} catch (error) {
|
||||
@@ -104,6 +111,7 @@ export function IdentityManagerModal({ isOpen, onClose }: IdentityManagerModalPr
|
||||
});
|
||||
|
||||
updateIdentityLocal(identity.id, data);
|
||||
syncIdentities();
|
||||
setEditingId(null);
|
||||
toast.success(tNotif('identity_updated'));
|
||||
} catch (error) {
|
||||
@@ -133,6 +141,7 @@ export function IdentityManagerModal({ isOpen, onClose }: IdentityManagerModalPr
|
||||
try {
|
||||
await client.deleteIdentity(identity.id);
|
||||
removeIdentity(identity.id);
|
||||
syncIdentities();
|
||||
toast.success(tNotif('identity_deleted'));
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : t('validation_errors.unknown_error');
|
||||
|
||||
Reference in New Issue
Block a user