fix: directly set in-focus on scrolled task instead of recalculating geometry
Previously handleScrollFocus() recalculated the centered task during init, which could select a different task than the one scrollToTask() targeted due to scroll container clamping or DOM layout timing. Now the scrolled task directly receives the in-focus class, and handleScrollFocus is only used during user-initiated scroll events. Also removes the isInitializing flag as it's no longer needed.
This commit is contained in:
parent
1a23558cad
commit
2229fdd0ef
@ -5,7 +5,6 @@ let selectedTaskId = null;
|
|||||||
let sortableInstance = null;
|
let sortableInstance = null;
|
||||||
let persistTimer = null;
|
let persistTimer = null;
|
||||||
let currentUser = null;
|
let currentUser = null;
|
||||||
let isInitializing = false;
|
|
||||||
|
|
||||||
async function loadGoals() {
|
async function loadGoals() {
|
||||||
try {
|
try {
|
||||||
@ -38,7 +37,6 @@ async function loadGoals() {
|
|||||||
async function loadTasks() {
|
async function loadTasks() {
|
||||||
if (!selectedGoalId) return;
|
if (!selectedGoalId) return;
|
||||||
|
|
||||||
isInitializing = true;
|
|
||||||
try {
|
try {
|
||||||
tasks = await get(`/api/tasks?goal_id=${selectedGoalId}`);
|
tasks = await get(`/api/tasks?goal_id=${selectedGoalId}`);
|
||||||
|
|
||||||
@ -49,7 +47,10 @@ async function loadTasks() {
|
|||||||
const savedTaskId = currentGoal ? currentGoal.selected_task_id : null;
|
const savedTaskId = currentGoal ? currentGoal.selected_task_id : null;
|
||||||
const savedTaskExists = savedTaskId && tasks.some(t => t.id === savedTaskId);
|
const savedTaskExists = savedTaskId && tasks.some(t => t.id === savedTaskId);
|
||||||
|
|
||||||
|
let focusTaskId = null;
|
||||||
|
|
||||||
if (savedTaskExists) {
|
if (savedTaskExists) {
|
||||||
|
focusTaskId = savedTaskId;
|
||||||
scrollToTask(savedTaskId);
|
scrollToTask(savedTaskId);
|
||||||
selectedTaskId = savedTaskId;
|
selectedTaskId = savedTaskId;
|
||||||
if (isLandscapeMode()) {
|
if (isLandscapeMode()) {
|
||||||
@ -58,6 +59,7 @@ async function loadTasks() {
|
|||||||
} else {
|
} else {
|
||||||
const doingTask = tasks.find(t => t.status === "doing");
|
const doingTask = tasks.find(t => t.status === "doing");
|
||||||
if (doingTask) {
|
if (doingTask) {
|
||||||
|
focusTaskId = doingTask.id;
|
||||||
scrollToTask(doingTask.id);
|
scrollToTask(doingTask.id);
|
||||||
if (isLandscapeMode()) {
|
if (isLandscapeMode()) {
|
||||||
selectTask(doingTask.id);
|
selectTask(doingTask.id);
|
||||||
@ -67,16 +69,23 @@ async function loadTasks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Directly set in-focus on the scrolled task instead of recalculating
|
||||||
|
if (focusTaskId) {
|
||||||
|
document.querySelectorAll(".task-item.in-focus").forEach(el => el.classList.remove("in-focus"));
|
||||||
|
const focusEl = document.querySelector(`[data-task-id="${focusTaskId}"]`);
|
||||||
|
if (focusEl) {
|
||||||
|
focusEl.classList.add("in-focus");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
initScrollFocus();
|
initScrollFocus();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to load tasks:", error);
|
console.error("Failed to load tasks:", error);
|
||||||
} finally {
|
|
||||||
isInitializing = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function persistSelectedTask(taskId) {
|
async function persistSelectedTask(taskId) {
|
||||||
if (!selectedGoalId || isInitializing) return;
|
if (!selectedGoalId) return;
|
||||||
try {
|
try {
|
||||||
await patch(`/api/goals/${selectedGoalId}/selected-task`, { task_id: taskId });
|
await patch(`/api/goals/${selectedGoalId}/selected-task`, { task_id: taskId });
|
||||||
const goal = goals.find(g => g.id === selectedGoalId);
|
const goal = goals.find(g => g.id === selectedGoalId);
|
||||||
@ -161,11 +170,6 @@ function initScrollFocus() {
|
|||||||
|
|
||||||
scrollView.removeEventListener("scroll", handleScrollFocus);
|
scrollView.removeEventListener("scroll", handleScrollFocus);
|
||||||
scrollView.removeEventListener("scroll", handleScrollSave);
|
scrollView.removeEventListener("scroll", handleScrollSave);
|
||||||
|
|
||||||
// Initial call to set in-focus class (before binding scroll handler)
|
|
||||||
handleScrollFocus();
|
|
||||||
|
|
||||||
// Bind scroll handlers after initial setup
|
|
||||||
scrollView.addEventListener("scroll", handleScrollFocus);
|
scrollView.addEventListener("scroll", handleScrollFocus);
|
||||||
scrollView.addEventListener("scroll", handleScrollSave);
|
scrollView.addEventListener("scroll", handleScrollSave);
|
||||||
}
|
}
|
||||||
@ -207,11 +211,9 @@ function handleScrollFocus() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleScrollSave() {
|
function handleScrollSave() {
|
||||||
// Save the task that has in-focus class (determined by handleScrollFocus)
|
|
||||||
const inFocusTask = document.querySelector(".task-item.in-focus");
|
const inFocusTask = document.querySelector(".task-item.in-focus");
|
||||||
console.log("handleScrollSave: inFocusTask=", inFocusTask?.dataset.taskId, "isInitializing=", isInitializing);
|
|
||||||
|
|
||||||
if (inFocusTask && !isInitializing) {
|
if (inFocusTask) {
|
||||||
const taskId = parseInt(inFocusTask.dataset.taskId);
|
const taskId = parseInt(inFocusTask.dataset.taskId);
|
||||||
clearTimeout(persistTimer);
|
clearTimeout(persistTimer);
|
||||||
persistTimer = setTimeout(() => persistSelectedTask(taskId), 400);
|
persistTimer = setTimeout(() => persistSelectedTask(taskId), 400);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user