sync tasks
This commit is contained in:
parent
dcc64827fa
commit
de973a98de
@ -1,7 +1,7 @@
|
|||||||
root = true
|
root = true
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
indent_style = tab
|
indent_style = space
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|||||||
@ -2,39 +2,11 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { render, Box, Text, useApp, useInput } from "ink";
|
import { render, Box, Text, useApp, useInput } from "ink";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import path from "path";
|
|
||||||
import { execSync, spawn } from "child_process";
|
import { execSync, spawn } from "child_process";
|
||||||
import { fileURLToPath } from "url";
|
import { loadTasks, saveTasks, commitAndPushTasks, pullTasks } from "./tasks.js";
|
||||||
import { Tabs, Tab } from 'ink-tab';
|
import { Tabs, Tab } from 'ink-tab';
|
||||||
import Scrollbar from "./scrollbar.js";
|
import Scrollbar from "./scrollbar.js";
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
|
||||||
const __dirname = path.dirname(__filename);
|
|
||||||
const TASK_FILE = path.join(__dirname, "tasks.json");
|
|
||||||
|
|
||||||
const loadTasks = () => {
|
|
||||||
try {
|
|
||||||
return ensureIds(JSON.parse(fs.readFileSync(TASK_FILE, "utf8")));
|
|
||||||
} catch {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const ensureIds = (tasks) => {
|
|
||||||
return tasks.map(task => {
|
|
||||||
if (!task.id) {
|
|
||||||
task.id = randomId();
|
|
||||||
}
|
|
||||||
if (task.subtasks && task.subtasks.length > 0) {
|
|
||||||
task.subtasks = ensureIds(task.subtasks);
|
|
||||||
}
|
|
||||||
return task;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const saveTasks = (tasks) => {
|
|
||||||
const updatedTasks = ensureIds(tasks);
|
|
||||||
fs.writeFileSync(TASK_FILE, JSON.stringify(updatedTasks, null, 2));
|
|
||||||
};
|
|
||||||
|
|
||||||
const countIncompleteSubtasks = (task) => {
|
const countIncompleteSubtasks = (task) => {
|
||||||
if (!task.subtasks || task.subtasks.length === 0) return 0;
|
if (!task.subtasks || task.subtasks.length === 0) return 0;
|
||||||
@ -139,13 +111,13 @@ export default function TaskApp() {
|
|||||||
fs.writeFileSync(tempFile, task.content || task.name);
|
fs.writeFileSync(tempFile, task.content || task.name);
|
||||||
try {
|
try {
|
||||||
// Run Neovim in a tmux split and use "wait-for" to track when it closes
|
// Run Neovim in a tmux split and use "wait-for" to track when it closes
|
||||||
execSync(`tmux split-window -h 'nvim ${tempFile}; tmux wait-for -S nvim_done'`);
|
execSync(`tmux split-window -h 'n ${tempFile}; tmux wait-for -S nvim_done'`);
|
||||||
|
|
||||||
// Wait for Neovim to exit (blocks execution until the user quits Neovim)
|
// Wait for Neovim to exit (blocks execution until the user quits Neovim)
|
||||||
execSync("tmux wait-for nvim_done");
|
execSync("tmux wait-for nvim_done");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// If tmux is not available, open Neovim normally
|
// If tmux is not available, open Neovim normally
|
||||||
spawn("nvim", [tempFile], { stdio: "inherit" });
|
spawn("n", [tempFile], { stdio: "inherit" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const editedTask = fs.readFileSync(tempFile, "utf8").trim();
|
const editedTask = fs.readFileSync(tempFile, "utf8").trim();
|
||||||
@ -303,6 +275,18 @@ export default function TaskApp() {
|
|||||||
setCutTask(null);
|
setCutTask(null);
|
||||||
log(`Moved task: ${cutTask.task.name}`);
|
log(`Moved task: ${cutTask.task.name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (input === "S") {
|
||||||
|
const confirmation = execSync(`echo "push\npull" | fzf --prompt 'Sync'`, { stdio: "pipe" }).toString().trim();
|
||||||
|
if (confirmation === "push") {
|
||||||
|
commitAndPushTasks(log)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (confirmation === "pull") {
|
||||||
|
pullTasks(log)
|
||||||
|
setTasks(loadTasks(), log)
|
||||||
|
}
|
||||||
|
}
|
||||||
if (input === "?") {
|
if (input === "?") {
|
||||||
log("==========================");
|
log("==========================");
|
||||||
log("Keybindings:");
|
log("Keybindings:");
|
||||||
@ -314,6 +298,7 @@ export default function TaskApp() {
|
|||||||
log("a - Add task");
|
log("a - Add task");
|
||||||
log("s - Add subtask");
|
log("s - Add subtask");
|
||||||
log("e - Edit task in Neovim");
|
log("e - Edit task in Neovim");
|
||||||
|
log("S - Sync (Push/Pull)");
|
||||||
log("space - Toggle completion");
|
log("space - Toggle completion");
|
||||||
log("/ - Search");
|
log("/ - Search");
|
||||||
log("? - Show help");
|
log("? - Show help");
|
||||||
|
|||||||
59
source/tasks.js
Normal file
59
source/tasks.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
|
||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
if (!process.env.TD_TASK_DIR) {
|
||||||
|
throw new Error("Environment variable TD_TASK_DIR is not defined");
|
||||||
|
}
|
||||||
|
const TASK_FILE = path.join(process.env.TD_TASK_DIR, "tasks.json");
|
||||||
|
|
||||||
|
|
||||||
|
const ensureIds = (tasks) => {
|
||||||
|
return tasks.map(task => {
|
||||||
|
if (!task.id) {
|
||||||
|
task.id = randomId();
|
||||||
|
}
|
||||||
|
if (task.subtasks && task.subtasks.length > 0) {
|
||||||
|
task.subtasks = ensureIds(task.subtasks);
|
||||||
|
}
|
||||||
|
return task;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export function loadTasks() {
|
||||||
|
try {
|
||||||
|
return ensureIds(JSON.parse(fs.readFileSync(TASK_FILE, "utf8")));
|
||||||
|
} catch {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function saveTasks(tasks) {
|
||||||
|
const updatedTasks = ensureIds(tasks);
|
||||||
|
fs.writeFileSync(TASK_FILE, JSON.stringify(updatedTasks, null, 2));
|
||||||
|
};
|
||||||
|
|
||||||
|
import { execSync } from "child_process";
|
||||||
|
|
||||||
|
export function commitAndPushTasks(log) {
|
||||||
|
const currentDateTime = new Date().toISOString();
|
||||||
|
const commitMessage = `Update tasks.json - ${currentDateTime}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
execSync(`git -C ${process.env.TD_TASK_DIR} add tasks.json`, { stdio: "pipe" });
|
||||||
|
execSync(`git -C ${process.env.TD_TASK_DIR} commit -m "${commitMessage}"`, { stdio: "pipe" });
|
||||||
|
execSync(`git -C ${process.env.TD_TASK_DIR} push origin`, { stdio: "pipe" });
|
||||||
|
} catch (error) {
|
||||||
|
log("Failed to commit and push tasks.json:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function pullTasks() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
execSync(`git -C ${process.env.TD_TASK_DIR} restore tasks.json`, { stdio: "pipe" });
|
||||||
|
execSync(`git -C ${process.env.TD_TASK_DIR} pull`, { stdio: "pipe" });
|
||||||
|
} catch (error) {
|
||||||
|
log("Failed to pull tasks.json:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user