Fix body field mismatch when switching between items in edit dialog
The RichTextEditor was not updating its content when switching from one item to another because initializedRef was only reset when value became null. Now uses prevValueRef to properly detect value changes.
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 338 KiB After Width: | Height: | Size: 334 KiB |
+5
-12
@@ -10,27 +10,20 @@ function RichTextEditor({ value, onChange, placeholder = "Add details...", colla
|
||||
const [copyMenuPos, setCopyMenuPos] = useStateD({ x: 0, y: 0 });
|
||||
const toolbarRef = useRefD(null);
|
||||
const isEditingRef = useRefD(false);
|
||||
const initializedRef = useRefD(false);
|
||||
const prevValueRef = useRefD(value);
|
||||
|
||||
// Initialize editor content only when value changes externally (not from our own edits)
|
||||
useEffectD(() => {
|
||||
if (editorRef.current && value !== undefined && !isEditingRef.current) {
|
||||
if (editorRef.current && !isEditingRef.current) {
|
||||
// Update if value changed from previous or editor is empty
|
||||
if (prevValueRef.current !== value || editorRef.current.innerHTML === '') {
|
||||
const html = MarkdownUtils.toHtml(value || '');
|
||||
// Only set innerHTML on first load or when value is reset externally
|
||||
if (!initializedRef.current || editorRef.current.innerHTML === '') {
|
||||
editorRef.current.innerHTML = html;
|
||||
initializedRef.current = true;
|
||||
prevValueRef.current = value;
|
||||
}
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
// Reset initialized flag when dialog closes/opens (value becomes null/undefined)
|
||||
useEffectD(() => {
|
||||
if (value === null || value === undefined) {
|
||||
initializedRef.current = false;
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
const handleInput = useCallbackD(() => {
|
||||
if (editorRef.current) {
|
||||
isEditingRef.current = true;
|
||||
|
||||
+8
-6
@@ -79,12 +79,13 @@ const Parser = {
|
||||
// Check for body line (starts with whitespace + "> ")
|
||||
const bodyMatch = line.match(/^(\s*)>\s?(.*)$/);
|
||||
if (bodyMatch) {
|
||||
// Body line - attach to current item at matching depth
|
||||
const bodyDepth = bodyMatch[1].length / 2;
|
||||
// Body line - attach to the most recent item in the stack
|
||||
// Body indent is one level deeper than its parent item (e.g., item at depth 0 has body at depth 1)
|
||||
const bodyIndent = bodyMatch[1].length / 2;
|
||||
const bodyLine = bodyMatch[2];
|
||||
// Find the item at this depth
|
||||
// Find the item whose depth is bodyIndent - 1 (body is indented under its item)
|
||||
for (let j = stack.length - 1; j >= 0; j--) {
|
||||
if (stack[j].depth === bodyDepth && stack[j].item) {
|
||||
if (stack[j].item && stack[j].depth === bodyIndent - 1) {
|
||||
if (!stack[j].item.body) stack[j].item.body = '';
|
||||
else stack[j].item.body += '\n';
|
||||
stack[j].item.body += bodyLine;
|
||||
@@ -165,10 +166,11 @@ const Parser = {
|
||||
const metaStr = meta.length ? ` *(${meta.join(', ')})*` : '';
|
||||
const prefix = it.priority ? `[${it.priority}] ` : '';
|
||||
lines.push(`${indent}- [${GLYPH[it.status] || ' '}] ${prefix}${it.title}${metaStr}`);
|
||||
// Serialize body as indented blockquote lines
|
||||
// Serialize body as indented blockquote lines (one level deeper than item)
|
||||
if (it.body) {
|
||||
const bodyIndent = ' '.repeat(depth + 1);
|
||||
for (const bodyLine of it.body.split('\n')) {
|
||||
lines.push(`${indent}> ${bodyLine}`);
|
||||
lines.push(`${bodyIndent}> ${bodyLine}`);
|
||||
}
|
||||
}
|
||||
if (it.children?.length) {
|
||||
|
||||
+13
-18
@@ -2802,12 +2802,13 @@ const Parser = {
|
||||
// Check for body line (starts with whitespace + "> ")
|
||||
const bodyMatch = line.match(/^(\s*)>\s?(.*)$/);
|
||||
if (bodyMatch) {
|
||||
// Body line - attach to current item at matching depth
|
||||
const bodyDepth = bodyMatch[1].length / 2;
|
||||
// Body line - attach to the most recent item in the stack
|
||||
// Body indent is one level deeper than its parent item (e.g., item at depth 0 has body at depth 1)
|
||||
const bodyIndent = bodyMatch[1].length / 2;
|
||||
const bodyLine = bodyMatch[2];
|
||||
// Find the item at this depth
|
||||
// Find the item whose depth is bodyIndent - 1 (body is indented under its item)
|
||||
for (let j = stack.length - 1; j >= 0; j--) {
|
||||
if (stack[j].depth === bodyDepth && stack[j].item) {
|
||||
if (stack[j].item && stack[j].depth === bodyIndent - 1) {
|
||||
if (!stack[j].item.body) stack[j].item.body = '';else stack[j].item.body += '\n';
|
||||
stack[j].item.body += bodyLine;
|
||||
break;
|
||||
@@ -2904,10 +2905,11 @@ const Parser = {
|
||||
const metaStr = meta.length ? ` *(${meta.join(', ')})*` : '';
|
||||
const prefix = it.priority ? `[${it.priority}] ` : '';
|
||||
lines.push(`${indent}- [${GLYPH[it.status] || ' '}] ${prefix}${it.title}${metaStr}`);
|
||||
// Serialize body as indented blockquote lines
|
||||
// Serialize body as indented blockquote lines (one level deeper than item)
|
||||
if (it.body) {
|
||||
const bodyIndent = ' '.repeat(depth + 1);
|
||||
for (const bodyLine of it.body.split('\n')) {
|
||||
lines.push(`${indent}> ${bodyLine}`);
|
||||
lines.push(`${bodyIndent}> ${bodyLine}`);
|
||||
}
|
||||
}
|
||||
if (it.children?.length) {
|
||||
@@ -4647,26 +4649,19 @@ function RichTextEditor({
|
||||
});
|
||||
const toolbarRef = useRefD(null);
|
||||
const isEditingRef = useRefD(false);
|
||||
const initializedRef = useRefD(false);
|
||||
const prevValueRef = useRefD(value);
|
||||
|
||||
// Initialize editor content only when value changes externally (not from our own edits)
|
||||
useEffectD(() => {
|
||||
if (editorRef.current && value !== undefined && !isEditingRef.current) {
|
||||
if (editorRef.current && !isEditingRef.current) {
|
||||
// Update if value changed from previous or editor is empty
|
||||
if (prevValueRef.current !== value || editorRef.current.innerHTML === '') {
|
||||
const html = MarkdownUtils.toHtml(value || '');
|
||||
// Only set innerHTML on first load or when value is reset externally
|
||||
if (!initializedRef.current || editorRef.current.innerHTML === '') {
|
||||
editorRef.current.innerHTML = html;
|
||||
initializedRef.current = true;
|
||||
prevValueRef.current = value;
|
||||
}
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
// Reset initialized flag when dialog closes/opens (value becomes null/undefined)
|
||||
useEffectD(() => {
|
||||
if (value === null || value === undefined) {
|
||||
initializedRef.current = false;
|
||||
}
|
||||
}, [value]);
|
||||
const handleInput = useCallbackD(() => {
|
||||
if (editorRef.current) {
|
||||
isEditingRef.current = true;
|
||||
|
||||
Reference in New Issue
Block a user