]> git.scottworley.com Git - vopamoi/blobdiff - vopamoi.ts
Hide task list during replay
[vopamoi] / vopamoi.ts
index bdc8b0d2bf9acffb6bb34416b7fa165ea0227a26..f550fa1cbbbd1ea9fa309a60d0d5e549dd5aacf0 100644 (file)
@@ -207,6 +207,7 @@ function Log(prefix: string = "vp-") {
     },
 
     replay: function () {
+      document.getElementById("tasks")!.style.display = "none";
       while (true) {
         const entry = window.localStorage.getItem(`${prefix}${next_log_index}`);
         if (entry === null) {
@@ -215,6 +216,7 @@ function Log(prefix: string = "vp-") {
         this.apply(entry);
         next_log_index++;
       }
+      document.getElementById("tasks")!.style.display = "";
     },
   };
 }
@@ -297,9 +299,6 @@ function BrowserUI() {
         this.firstVisibleTask()?.focus();
       }
       input.value = "";
-      if (currentTagView) {
-        ui.addTag(task.getAttribute("data-created")!, currentTagView);
-      }
       if (event.getModifierState("Control")) {
         this.makeBottomPriority(task);
       }
@@ -381,8 +380,9 @@ function BrowserUI() {
       return target as HTMLElement;
     },
 
-    firstVisibleTask: function () {
-      for (const task of document.getElementsByClassName("task")) {
+    firstVisibleTask: function (root: Element | null = null) {
+      if (root === null) root = document.body;
+      for (const task of root.getElementsByClassName("task")) {
         const state = task.getAttribute("data-state");
         if (
           task instanceof HTMLElement &&
@@ -441,7 +441,21 @@ function BrowserUI() {
       task instanceof HTMLElement && task.focus();
     },
 
-    moveCursor: function (offset: number): boolean {
+    moveCursorLeft: function () {
+      const active = this.currentTask();
+      if (!active) return false;
+      if (active.parentElement!.classList.contains("task")) {
+        active.parentElement!.focus();
+      }
+    },
+
+    moveCursorRight: function () {
+      const active = this.currentTask();
+      if (!active) return false;
+      (this.firstVisibleTask(active) as HTMLElement | null)?.focus();
+    },
+
+    moveCursorVertically: function (offset: number): boolean {
       const active = this.currentTask();
       if (!active) return false;
       const dest = this.visibleTaskAtOffset(active, offset);
@@ -474,8 +488,12 @@ function BrowserUI() {
 
     resetTagView: function () {
       currentTagView = null;
-      for (const task of document.getElementsByClassName("task")) {
+      const taskList = document.getElementById("tasks")!;
+      for (const task of Array.from(document.getElementsByClassName("task"))) {
         task.classList.remove("hide");
+        if (task.parentElement !== taskList) {
+          Model.insertInPriorityOrder(task, taskList);
+        }
       }
     },
 
@@ -513,22 +531,55 @@ function BrowserUI() {
       if (newState === oldState) return;
       const createTimestamp = task.getAttribute("data-created")!;
       if (currentViewState !== "all" || newState == "deleted") {
-        this.moveCursor(1) || this.moveCursor(-1);
+        this.moveCursorVertically(1) || this.moveCursorVertically(-1);
       }
       return ui.setState(createTimestamp, newState, oldState);
     },
 
-    setTagView: function () {
-      const target = this.currentTag();
-      if (!target) return;
-      const tag = target.textContent!;
+    setTagView: function (tag: string | null = null) {
+      if (tag === null) {
+        const target = this.currentTag();
+        if (!target) return;
+        tag = target.textContent!;
+      }
+
+      if (currentTagView !== null) {
+        this.resetTagView();
+      }
+
+      const tasksWithTag = new Map();
       for (const task of document.getElementsByClassName("task")) {
+        if (Model.hasTag(task, tag)) {
+          tasksWithTag.set(task.getElementsByClassName("desc")[0].textContent, [Model.getPriority(task), task]);
+        }
+      }
+
+      function highestPrioritySuperTask(t: Element) {
+        var maxPriority = -1;
+        var superTask = null;
+        for (const child of t.getElementsByClassName("tag")) {
+          const e = tasksWithTag.get(child.textContent);
+          if (e !== undefined && e[0] > maxPriority) {
+            maxPriority = e[0];
+            superTask = e[1];
+          }
+        }
+        return superTask;
+      }
+
+      for (const task of Array.from(document.getElementsByClassName("task"))) {
         if (Model.hasTag(task, tag)) {
           task.classList.remove("hide");
         } else {
-          task.classList.add("hide");
+          const superTask = highestPrioritySuperTask(task);
+          if (superTask !== null) {
+            Model.insertInPriorityOrder(task, superTask);
+          } else {
+            task.classList.add("hide");
+          }
         }
       }
+
       currentTagView = tag;
     },
 
@@ -549,6 +600,9 @@ function BrowserUI() {
     },
 
     setUntaggedView: function () {
+      if (currentTagView !== null) {
+        this.resetTagView();
+      }
       for (const task of document.getElementsByClassName("task")) {
         if (task.getElementsByClassName("tag").length === 0) {
           task.classList.remove("hide");
@@ -603,8 +657,10 @@ function handleKey(event: any) {
           if (event.key == "e") return window.scrollBy(0, (inputCount ?? 1) * scrollIncrement);
           if (event.key == "y") return window.scrollBy(0, (inputCount ?? 1) * -scrollIncrement);
         } else {
-          if (event.key == "j") return browserUI.moveCursor(inputCount ?? 1);
-          if (event.key == "k") return browserUI.moveCursor(-(inputCount ?? 1));
+          if (event.key == "h") return browserUI.moveCursorLeft();
+          if (event.key == "l") return browserUI.moveCursorRight();
+          if (event.key == "j") return browserUI.moveCursorVertically(inputCount ?? 1);
+          if (event.key == "k") return browserUI.moveCursorVertically(-(inputCount ?? 1));
           if (event.key == "J") return browserUI.moveTask(inputCount ?? 1);
           if (event.key == "K") return browserUI.moveTask(-(inputCount ?? 1));
           if (event.key == "G") return browserUI.jumpCursor(inputCount ?? MAX_SAFE_INTEGER);
@@ -635,6 +691,7 @@ function handleKey(event: any) {
       if (event.key == "c") return browserUI.setView("cancelled");
       if (event.key == "d") return browserUI.setView("done");
       if (event.key == "i") return browserUI.setUntaggedView();
+      if (event.key == "p") return browserUI.setTagView("Project");
       if (event.key == "q") return browserUI.setView("todo");
       if (event.key == "s") return (inputState = InputState.VS);
       if (event.key == "T") return browserUI.resetTagView();