]> git.scottworley.com Git - vopamoi/blobdiff - vopamoi.ts
Nested tag view
[vopamoi] / vopamoi.ts
index 33e37a37e851db876b260dc14c406f6ebc5e6845..f624db13f4774f2e9e19e32186082a9a75ed00a4 100644 (file)
@@ -120,6 +120,17 @@ const Model = {
     }
   },
 
+  insertInPriorityOrder: function (task: Element, dest: Element) {
+    const priority = this.getPriority(task);
+    for (const t of dest.children) {
+      if (t !== task && this.getPriority(t) < priority) {
+        dest.insertBefore(task, t);
+        return;
+      }
+    }
+    dest.appendChild(task);
+  },
+
   removeTag: function (createTimestamp: string, tagName: string) {
     const task = this.getTask(createTimestamp);
     if (!task) return null;
@@ -133,13 +144,7 @@ const Model = {
     const target = this.getTask(createTimestamp);
     if (!target) return null;
     target.setAttribute("data-priority", `${priority}`);
-    for (const task of document.getElementsByClassName("task")) {
-      if (task !== target && this.getPriority(task) < priority) {
-        task.parentElement!.insertBefore(target, task);
-        return target;
-      }
-    }
-    document.getElementById("tasks")!.appendChild(target);
+    this.insertInPriorityOrder(target, target.parentElement!);
     return target;
   },
 
@@ -276,6 +281,7 @@ function BrowserUI() {
     todo: "White",
     waiting: "MediumOrchid",
   };
+  var currentTagView: string | null = null;
   var currentViewState = "todo";
   var taskFocusedBeforeJumpingToInput: HTMLElement | null = null;
   var lastTagNameEntered = "";
@@ -291,6 +297,9 @@ function BrowserUI() {
         this.firstVisibleTask()?.focus();
       }
       input.value = "";
+      if (currentTagView) {
+        ui.addTag(task.getAttribute("data-created")!, currentTagView);
+      }
       if (event.getModifierState("Control")) {
         this.makeBottomPriority(task);
       }
@@ -464,8 +473,13 @@ function BrowserUI() {
     },
 
     resetTagView: function () {
-      for (const task of document.getElementsByClassName("task")) {
+      currentTagView = null;
+      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);
+        }
       }
     },
 
@@ -512,13 +526,45 @@ function BrowserUI() {
       const target = this.currentTag();
       if (!target) return;
       const 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;
     },
 
     setView: function (state: string) {
@@ -538,6 +584,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");