fix(signatures): apply reply signature to replies and forwards
Publish Docker Image / prepare (push) Successful in 3s
Publish Docker Image / build (linux/amd64, ubuntu-latest) (push) Failing after 19s
Publish Docker Image / build (linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
Publish Docker Image / merge (push) Canceled after 0s

This commit is contained in:
2026-08-23 19:04:49 +02:00
parent 33ca4bae37
commit e696c65f75
2 changed files with 28 additions and 9 deletions
+16 -6
View File
@@ -653,6 +653,15 @@ export function EmailComposer({
? currentIdentity
: primaryIdentity;
// The signature store (default/reply/per-identity) takes precedence over the
// legacy per-identity html/text signature. `selectedSignature` is resolved in
// resolveStoreSignatureId for the current mode (compose → default; reply/
// forward → reply), so replies and forwards pick up the reply signature.
// Falls back to the legacy identity signature when no store signature is set.
const effectiveSignature = selectedSignature
? { htmlSignature: selectedSignature.body, textSignature: selectedSignature.plainText }
: signatureIdentity;
// Hold the TipTap editor instance so we can swap the embedded signature
// when the user switches identity in "above quote" mode without rebuilding
// the whole body (which would lose user edits to the surrounding draft).
@@ -1883,6 +1892,7 @@ export function EmailComposer({
// duplicate it.
const signatureAlreadyInBody =
shouldEmbedSignatureInNewMail ||
(!plainTextMode && !!selectedSignature && mode === 'compose') ||
((mode === 'reply' || mode === 'replyAll' || mode === 'forward') &&
signaturePosition === 'above_quote');
@@ -1890,11 +1900,11 @@ export function EmailComposer({
const buildSignatureHtml = (): string => {
if (signatureAlreadyInBody) return '';
const sep = signatureSeparatorEnabled ? `<br><br>-- <br>` : `<br><br>`;
if (signatureIdentity?.htmlSignature) {
return `${sep}${sanitizeSignatureHtml(signatureIdentity.htmlSignature)}`;
if (effectiveSignature?.htmlSignature) {
return `${sep}${sanitizeSignatureHtml(effectiveSignature.htmlSignature)}`;
}
if (signatureIdentity?.textSignature) {
return `${sep}${signatureIdentity.textSignature.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br>')}`;
if (effectiveSignature?.textSignature) {
return `${sep}${effectiveSignature.textSignature.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br>')}`;
}
return '';
};
@@ -1907,8 +1917,8 @@ export function EmailComposer({
// In plain text mode, send text/plain only (no HTML body)
const signatureOpts = { separator: signatureSeparatorEnabled };
const finalBody = plainTextMode
? (signatureAlreadyInBody ? body : appendPlainTextSignature(body, signatureIdentity, signatureOpts))
: (signatureAlreadyInBody ? htmlToPlainText(body) : appendPlainTextSignature(htmlToPlainText(body), signatureIdentity, signatureOpts));
? (signatureAlreadyInBody ? body : appendPlainTextSignature(body, effectiveSignature, signatureOpts))
: (signatureAlreadyInBody ? htmlToPlainText(body) : appendPlainTextSignature(htmlToPlainText(body), effectiveSignature, signatureOpts));
const rewritten = plainTextMode ? null : rewriteInlineImages(body);
const finalHtmlBody = plainTextMode