Compare commits
16 Commits
1f4efcd7b3
...
01ae9c964a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01ae9c964a | ||
|
|
5294446407 | ||
|
|
ab000bcd41 | ||
|
|
2229fdd0ef | ||
|
|
1a23558cad | ||
|
|
84181e1ec2 | ||
|
|
eca0cf4193 | ||
|
|
14ebbda585 | ||
|
|
fd92c6fe96 | ||
|
|
12610d26c0 | ||
|
|
1df90490e6 | ||
|
|
ca7bd7e24e | ||
|
|
025195be27 | ||
|
|
0f1fa712a9 | ||
|
|
df74f1b8a7 | ||
|
|
295fde8a75 |
@ -44,6 +44,7 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
height: 600px;
|
height: 600px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
position: relative;
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||||
|
|||||||
@ -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,31 +37,29 @@ 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}`);
|
||||||
console.log("loadTasks: got", tasks.length, "tasks");
|
|
||||||
console.log("Task order:", tasks.map(t => ({id: t.id, title: t.title, status: t.status})));
|
|
||||||
|
|
||||||
renderTasks();
|
renderTasks();
|
||||||
initSortable();
|
initSortable();
|
||||||
|
|
||||||
const currentGoal = goals.find(g => g.id === selectedGoalId);
|
const currentGoal = goals.find(g => g.id === selectedGoalId);
|
||||||
const savedTaskId = currentGoal ? currentGoal.selected_task_id : null;
|
const savedTaskId = currentGoal ? currentGoal.selected_task_id : null;
|
||||||
console.log("loadTasks: savedTaskId from goal =", savedTaskId);
|
|
||||||
const savedTaskExists = savedTaskId && tasks.some(t => t.id === savedTaskId);
|
const savedTaskExists = savedTaskId && tasks.some(t => t.id === savedTaskId);
|
||||||
console.log("loadTasks: savedTaskExists =", savedTaskExists);
|
|
||||||
|
let focusTaskId = null;
|
||||||
|
|
||||||
if (savedTaskExists) {
|
if (savedTaskExists) {
|
||||||
console.log("loadTasks: using savedTaskId path");
|
focusTaskId = savedTaskId;
|
||||||
scrollToTask(savedTaskId);
|
scrollToTask(savedTaskId);
|
||||||
|
selectedTaskId = savedTaskId;
|
||||||
if (isLandscapeMode()) {
|
if (isLandscapeMode()) {
|
||||||
selectTask(savedTaskId);
|
selectTask(savedTaskId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log("loadTasks: using fallback path");
|
|
||||||
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);
|
||||||
@ -72,22 +69,32 @@ async function loadTasks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wait one frame so the async scroll event from scrollToTask fires first,
|
||||||
|
// then set in-focus and bind handlers after it has been consumed.
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
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);
|
||||||
if (goal) {
|
if (goal) {
|
||||||
goal.selected_task_id = taskId;
|
goal.selected_task_id = taskId;
|
||||||
}
|
}
|
||||||
|
console.log("Saved selected task:", taskId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to persist selected task:", error);
|
console.error("Failed to persist selected task:", error);
|
||||||
}
|
}
|
||||||
@ -150,19 +157,13 @@ function initSortable() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function scrollToTask(taskId) {
|
function scrollToTask(taskId) {
|
||||||
console.log("scrollToTask called:", taskId);
|
|
||||||
const taskElement = document.querySelector(`[data-task-id="${taskId}"]`);
|
const taskElement = document.querySelector(`[data-task-id="${taskId}"]`);
|
||||||
if (taskElement) {
|
if (taskElement) {
|
||||||
const scrollView = document.getElementById("scroll-view");
|
const scrollView = document.getElementById("scroll-view");
|
||||||
const taskTop = taskElement.offsetTop;
|
const taskTop = taskElement.offsetTop;
|
||||||
const scrollViewHeight = scrollView.clientHeight;
|
const scrollViewHeight = scrollView.clientHeight;
|
||||||
const taskHeight = taskElement.offsetHeight;
|
const taskHeight = taskElement.offsetHeight;
|
||||||
const targetScrollTop = taskTop - (scrollViewHeight / 2) + (taskHeight / 2);
|
scrollView.scrollTop = taskTop - (scrollViewHeight / 2) + (taskHeight / 2);
|
||||||
console.log("Scrolling to:", targetScrollTop, "element offsetTop:", taskTop);
|
|
||||||
scrollView.scrollTop = targetScrollTop;
|
|
||||||
console.log("scrollTop after set:", scrollView.scrollTop);
|
|
||||||
} else {
|
|
||||||
console.log("Task element not found for id:", taskId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +171,9 @@ function initScrollFocus() {
|
|||||||
const scrollView = document.getElementById("scroll-view");
|
const scrollView = document.getElementById("scroll-view");
|
||||||
|
|
||||||
scrollView.removeEventListener("scroll", handleScrollFocus);
|
scrollView.removeEventListener("scroll", handleScrollFocus);
|
||||||
|
scrollView.removeEventListener("scroll", handleScrollSave);
|
||||||
scrollView.addEventListener("scroll", handleScrollFocus);
|
scrollView.addEventListener("scroll", handleScrollFocus);
|
||||||
|
scrollView.addEventListener("scroll", handleScrollSave);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleScrollFocus() {
|
function handleScrollFocus() {
|
||||||
@ -201,9 +204,6 @@ function handleScrollFocus() {
|
|||||||
|
|
||||||
const taskId = parseInt(closestItem.dataset.taskId);
|
const taskId = parseInt(closestItem.dataset.taskId);
|
||||||
|
|
||||||
clearTimeout(persistTimer);
|
|
||||||
persistTimer = setTimeout(() => persistSelectedTask(taskId), 400);
|
|
||||||
|
|
||||||
if (isLandscapeMode()) {
|
if (isLandscapeMode()) {
|
||||||
if (taskId !== selectedTaskId) {
|
if (taskId !== selectedTaskId) {
|
||||||
selectTask(taskId);
|
selectTask(taskId);
|
||||||
@ -212,6 +212,16 @@ function handleScrollFocus() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleScrollSave() {
|
||||||
|
const inFocusTask = document.querySelector(".task-item.in-focus");
|
||||||
|
|
||||||
|
if (inFocusTask) {
|
||||||
|
const taskId = parseInt(inFocusTask.dataset.taskId);
|
||||||
|
clearTimeout(persistTimer);
|
||||||
|
persistTimer = setTimeout(() => persistSelectedTask(taskId), 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function isLandscapeMode() {
|
function isLandscapeMode() {
|
||||||
return window.innerWidth > window.innerHeight && window.innerWidth >= 1024;
|
return window.innerWidth > window.innerHeight && window.innerWidth >= 1024;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user