fix: keep the text typed in the Sieve editor when the script refreshes (bulwarkmail/webmail#1162)

This commit is contained in:
Linus Rath
2026-10-31 04:07:12 +01:00
parent dcbfc907fa
commit 6c3046c8dc
3 changed files with 26 additions and 3 deletions
+7 -3
View File
@@ -11,6 +11,7 @@ import Button from '../Button';
import { useLocaleStore } from '../../stores/locale-store';
import { SafeAreaModal } from '../SafeAreaModal';
import { MODAL_ORIENTATIONS } from '../../lib/modal-orientations';
import { seedsOnRender } from '../../lib/sieve/editor-seed';
interface SieveEditorSheetProps {
visible: boolean;
@@ -30,14 +31,17 @@ export function SieveEditorSheet({ visible, content, onSave, onClose, onValidate
const [validationResult, setValidationResult] = useState<{ isValid: boolean; errors?: string[] } | null>(null);
const [showSaveWarning, setShowSaveWarning] = useState(false);
// Re-seed the editor whenever it's (re)opened with fresh content. Keying the
// editor on `content` while closed avoids a stale draft on the next open.
// Seed the editor when it opens, with the script as it is then. A new
// `content` while it is open (a store refresh) must not wipe what was
// typed (#1162).
const wasVisible = React.useRef(false);
React.useEffect(() => {
if (visible) {
if (seedsOnRender(wasVisible.current, visible)) {
setScript(content);
setValidationResult(null);
setShowSaveWarning(false);
}
wasVisible.current = visible;
}, [visible, content]);
const lineCount = script.split('\n').length;
@@ -0,0 +1,11 @@
import { describe, expect, it } from 'vitest';
import { seedsOnRender } from '../editor-seed';
describe('seedsOnRender', () => {
it('seeds the Sieve editor when it opens, not when the script is refreshed while it is open (#1162)', () => {
expect(seedsOnRender(false, true)).toBe(true);
expect(seedsOnRender(true, true)).toBe(false);
expect(seedsOnRender(true, false)).toBe(false);
expect(seedsOnRender(false, false)).toBe(false);
});
});
+8
View File
@@ -0,0 +1,8 @@
/**
* Whether an editor sheet takes its content afresh: only when it opens. A
* new `content` while it is open (a store refresh) must not replace what the
* user typed (#1162).
*/
export function seedsOnRender(wasVisible: boolean, visible: boolean): boolean {
return visible && !wasVisible;
}