Commit 2e8c0bf3 by Sujeeth AV

Index.jsx

parent 77be3fa6
...@@ -14,6 +14,9 @@ export const Input = () => { ...@@ -14,6 +14,9 @@ export const Input = () => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [isNewTodoAdded, setIsNewTodoAdded] = useState(false); const [isNewTodoAdded, setIsNewTodoAdded] = useState(false);
const editableRef = useRef(null); const editableRef = useRef(null);
const lastCursorPos = useRef(0);
const debounceTimeout = useRef(null); const debounceTimeout = useRef(null);
const fetchTodos = useCallback(async () => { const fetchTodos = useCallback(async () => {
...@@ -32,37 +35,93 @@ export const Input = () => { ...@@ -32,37 +35,93 @@ export const Input = () => {
fetchTodos(); fetchTodos();
}, [fetchTodos]); }, [fetchTodos]);
const saveSelection = () => { const saveCursorPosition = () => {
const selection = window.getSelection(); try {
if (selection.rangeCount > 0) { if (editableRef.current) {
return selection.getRangeAt(0); const selection = window.getSelection();
if (selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
const preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(editableRef.current);
preCaretRange.setEnd(range.endContainer, range.endOffset);
lastCursorPos.current = preCaretRange.toString().length;
}
}
} catch (error) {
console.error("Error saving cursor position:", error);
} }
return null;
}; };
const restoreSelection = (savedRange) => { const restoreCursorPosition = () => {
if (!savedRange) return; try {
if (editableRef.current) {
const selection = window.getSelection(); const range = document.createRange();
selection.removeAllRanges(); const selection = window.getSelection();
selection.addRange(savedRange);
let found = false;
const findPosition = (node, remainingPos) => {
if (node.nodeType === Node.TEXT_NODE) {
const length = node.nodeValue.length;
if (remainingPos <= length) {
range.setStart(node, remainingPos);
found = true;
return;
}
remainingPos -= length;
} else {
for (let i = 0; i < node.childNodes.length && !found; i++) {
findPosition(node.childNodes[i], remainingPos);
}
}
};
findPosition(editableRef.current, lastCursorPos.current);
if (!found) {
range.selectNodeContents(editableRef.current);
range.collapse(false);
} else {
range.collapse(true);
}
selection.removeAllRanges();
selection.addRange(range);
}
} catch (error) {
console.error("Error restoring cursor position:", error);
}
}; };
useEffect(() => {
if (editableRef.current && editIndex !== null) {
try {
editableRef.current.focus();
setTimeout(restoreCursorPosition, 0);
} catch (error) {
console.error("Error focusing editable element:", error);
setEditIndex(null);
}
}
}, [editIndex, editedTask]);
const handleEdit = (e) => { const handleEdit = (e) => {
try { try {
const savedRange = saveSelection(); saveCursorPosition();
const newValue = e.currentTarget.textContent; const newValue = e.currentTarget.textContent;
setEditedTask(newValue); setEditedTask(newValue);
const updatedStore = [...store]; const updatedStore = [...store];
const original = updatedStore[editIndex]; const original = updatedStore[editIndex];
updatedStore[editIndex] = { ...original, task: newValue }; updatedStore[editIndex] = { ...original, task: newValue };
setStore(updatedStore); setStore(updatedStore);
if (debounceTimeout.current) { if (debounceTimeout.current) {
clearTimeout(debounceTimeout.current); clearTimeout(debounceTimeout.current);
} }
debounceTimeout.current = setTimeout(() => { debounceTimeout.current = setTimeout(() => {
uptTodo(original.id, { uptTodo(original.id, {
id: original.id, id: original.id,
...@@ -72,14 +131,6 @@ export const Input = () => { ...@@ -72,14 +131,6 @@ export const Input = () => {
console.error("Error saving todo:", error); console.error("Error saving todo:", error);
}); });
}, 1000); }, 1000);
// Restore selection after state updates
setTimeout(() => {
if (editableRef.current) {
editableRef.current.focus();
restoreSelection(savedRange);
}
}, 0);
} catch (error) { } catch (error) {
console.error("Error during edit:", error); console.error("Error during edit:", error);
setEditIndex(null); setEditIndex(null);
...@@ -92,19 +143,6 @@ export const Input = () => { ...@@ -92,19 +143,6 @@ export const Input = () => {
try { try {
setEditIndex(index); setEditIndex(index);
setEditedTask(store[index].task); setEditedTask(store[index].task);
// Focus and set cursor at end by default
setTimeout(() => {
if (editableRef.current) {
editableRef.current.focus();
const range = document.createRange();
range.selectNodeContents(editableRef.current);
range.collapse(false);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
}, 0);
} catch (error) { } catch (error) {
console.error("Error starting edit:", error); console.error("Error starting edit:", error);
setEditIndex(null); setEditIndex(null);
...@@ -128,7 +166,6 @@ export const Input = () => { ...@@ -128,7 +166,6 @@ export const Input = () => {
setTimeout(() => setIsNewTodoAdded(false), 500); setTimeout(() => setIsNewTodoAdded(false), 500);
} }
}; };
const Delete = async (id) => { const Delete = async (id) => {
const confirmDelete = window.confirm("Are you sure you want to delete?"); const confirmDelete = window.confirm("Are you sure you want to delete?");
if (confirmDelete) { if (confirmDelete) {
...@@ -149,6 +186,7 @@ export const Input = () => { ...@@ -149,6 +186,7 @@ export const Input = () => {
completed: !newStore[index].completed completed: !newStore[index].completed
}; };
setStore(newStore); setStore(newStore);
await uptTodo(newStore[index].id, newStore[index]); await uptTodo(newStore[index].id, newStore[index]);
} catch (error) { } catch (error) {
console.error("Error toggling complete:", error); console.error("Error toggling complete:", error);
...@@ -171,15 +209,15 @@ export const Input = () => { ...@@ -171,15 +209,15 @@ export const Input = () => {
e.currentTarget.blur(); e.currentTarget.blur();
} }
}} }}
className={`${styles.task} ${store[editIndex]?.completed ? styles.completed : ''}`} className={`${styles.task} ${store[editIndex]?.completed ? 'completed' : ''}`}
dangerouslySetInnerHTML={{ __html: editedTask }}
style={{ style={{
display: 'inline-block', display: 'inline-block',
width: '100%', width:'100%',
boxSizing: 'border-box', boxSizing:'border-box'
outline: 'none'
}} }}
/> >
{editedTask}
</div>
); );
} catch (error) { } catch (error) {
console.error("Error rendering editable content:", error); console.error("Error rendering editable content:", error);
...@@ -188,7 +226,9 @@ export const Input = () => { ...@@ -188,7 +226,9 @@ export const Input = () => {
className={`${styles.task} ${store[editIndex]?.completed ? styles.completed : ''}`} className={`${styles.task} ${store[editIndex]?.completed ? styles.completed : ''}`}
onClick={() => startEdit(editIndex)} onClick={() => startEdit(editIndex)}
> >
{store[editIndex]?.task} {typeof store[editIndex]?.task === 'string'
? store[editIndex].task
: JSON.stringify(store[editIndex]?.task)}
</span> </span>
); );
} }
...@@ -229,4 +269,4 @@ export const Input = () => { ...@@ -229,4 +269,4 @@ export const Input = () => {
</div> </div>
</MyTask.Provider> </MyTask.Provider>
); );
}; };
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment