From 138e991a8e7006d92b79f6c18e194f879532ddbb Mon Sep 17 00:00:00 2001 From: nightwatch75 <30896720+nightwatch75@users.noreply.github.com> Date: Thu, 16 Jul 2026 01:42:00 +0200 Subject: [PATCH] =?UTF-8?q?Add=20nightwatch75/todo=200.0.7=20=E2=80=94=20p?= =?UTF-8?q?rioritised=20to-do=20list=20(bar=20widget=20+=20panel)=20(#18)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add nightwatch75/todo 0.0.6 Co-Authored-By: Claude Fable 5 * To Do 0.0.7: make priority sort a view; never rewrite the manual order Review fix: switching to priority mode used to sort the items array and persist it, destroying the manual ordering. items and the on-disk tasks array now always hold the manual order; priority mode stable-sorts a copy at render time only. Co-Authored-By: Claude Fable 5 --------- Co-authored-by: Massimiliano Co-authored-by: Claude Fable 5 --- todo/README.md | 106 +++++++ todo/panel.luau | 641 ++++++++++++++++++++++++++++++++++++++ todo/plugin.toml | 45 +++ todo/thumbnail.webp | Bin 0 -> 57206 bytes todo/todo.luau | 73 +++++ todo/translations/en.json | 30 ++ 6 files changed, 895 insertions(+) create mode 100644 todo/README.md create mode 100644 todo/panel.luau create mode 100644 todo/plugin.toml create mode 100644 todo/thumbnail.webp create mode 100644 todo/todo.luau create mode 100644 todo/translations/en.json diff --git a/todo/README.md b/todo/README.md new file mode 100644 index 0000000..22a3668 --- /dev/null +++ b/todo/README.md @@ -0,0 +1,106 @@ +# To Do + +A [noctalia](https://github.com/noctalia-dev/noctalia) v5 bar plugin: a +prioritised to-do list. Click the bar glyph to toggle a panel of task rows — +add tasks with **+**, tick them off (the text is struck through), delete them, +and set each task's priority. The list is kept sorted by priority and stored as +a single JSON file; no external commands are run. + +| Action | Effect | +|-------------------------------|-----------------------------------------------------| +| Left click (bar glyph) | Open/close the To Do panel | +| **+** (panel header) | Add a new task and start typing it | +| Sort toggle (panel header) | Switch ordering between **Priority** and **Manual** | +| Colour chip (row) | Cycle the task's priority: important → medium → low | +| ☰ grip (row, manual only) | Pick the row up / drop the held row here (reorder) | +| Click the text, or ✎ (pencil) | Edit the task's text | +| **Enter**, or ✓ (row) | Commit the edit — the row goes back to a static line | +| ☐ / ☑ button (row) | Toggle done/to-do (done tasks are struck through) | +| 🗑 button (row) | Delete the task | + +## Priorities + +Each task carries a priority, shown at the start of the row as a small coloured +square. Click the square to cycle it. A legend at the foot of the panel maps +each colour to its category: + +| Priority | Colour | +|-----------|--------| +| Important | red | +| Medium | amber | +| Low | green | + +## Ordering + +The panel header carries a toggle that switches between two ordering modes; the +choice is remembered. + +- **Priority** (default) — rows are sorted by priority: important first, then + medium, then low. Changing a task's priority moves it into its new group but + keeps its position relative to its peers; equal-priority rows are never + reshuffled. No grips are shown. +- **Manual** — rows keep the order you give them. Each row grows a ☰ grip on the + left; here changing a priority only recolours the chip and never moves the row. + +Priority mode is only a view: the stored order is always the manual one, so +switching between the two modes (as often as you like) never loses your custom +ordering. + +### Reordering in manual mode + +The noctalia plugin UI exposes no drag callbacks (only clicks), so the ☰ grip +reorders with two clicks instead of a drag: + +1. Click a row's ☰ grip — it lights up; that row is now "held". +2. Click another row's ☰ grip — the held row drops in just above it. +3. Click the held row's own grip again to cancel. + +## Editing + +Rows are static lines by default. Click a task's text (or its ✎ pencil button) +to edit it; press **Enter** or the ✓ button to commit back to a static line. A +new task (**+**) opens straight into edit mode — committing it while still empty +simply discards it. Edits are also autosaved after a short idle pause and on +close. + +Tick a task (☐ → ☑) to complete it — its text is struck through until you +un-tick it. The bar glyph's tooltip shows how many tasks are still to do. + +## Storage + +Tasks live in one file, `todo.json`, inside the configured **To Do folder** +(default `~/Documents/Todo`). It is a small JSON object, +`{ "version": 2, "sort": "priority" | "manual", "tasks": [ … ] }`, where `tasks` +is the array of `{ id, text, priority, done }` objects (in manual order) — easy +to read, hand-edit, sync, or back up. An older plain-array file is still read +automatically. The plugin runs no external programs. + +## Settings + +| Setting | What it does | +|--------------|----------------------------------------------------------| +| To Do folder | Where `todo.json` is stored (default `~/Documents/Todo`).| +| Bar glyph | The glyph shown for the widget on the bar. | + +## Install + +Install **To Do** from Noctalia's plugin store (*Settings → Plugins*), then add +the widget to a bar from *Settings → Bar*. Plugin options live in +*Settings → Plugins*. + +For local development, add your working copy as a path source instead +(`.luau` edits hot-reload): + +```sh +noctalia msg plugins source add dev path /path/to/plugins +noctalia msg plugins enable nightwatch75/todo +``` + +## Requirements + +- noctalia ≥ 5.0.0 +- No external dependencies + +## License + +MIT. diff --git a/todo/panel.luau b/todo/panel.luau new file mode 100644 index 0000000..663ea95 --- /dev/null +++ b/todo/panel.luau @@ -0,0 +1,641 @@ +--!nonstrict +-- To Do — a prioritised task list in an attached panel. +-- +-- A task is { id, text, priority, done }. The whole list is persisted to +-- /todo.json (noctalia.json) as an object { version, sort, tasks }: +-- `tasks` is the array — ALWAYS in manual order — and `sort` records the chosen +-- display mode. A legacy plain-array file is still read (treated as manual +-- order, sort defaulting to "priority"). Empty (blank-text) tasks are never +-- written: they only exist transiently while being entered. +-- +-- Ordering has two modes, switched from a header toggle. `items` (and the disk +-- array) hold the manual order in both; priority mode is a VIEW — a stable sort +-- applied at render time only — so switching modes never rewrites the user's +-- manual order: +-- * "priority" — rows display sorted important → medium → low; equal-priority +-- rows keep their manual relative order. No drag handles are shown. +-- * "manual" — the stored order is shown verbatim. A ☰ grip on each row +-- reorders it (see below); changing a priority only recolours the chip and +-- never moves the row. Because the noctalia plugin UI exposes no pointer +-- drag callbacks (only onClick), the grip works as a two-click grab/drop: +-- click a row's grip to pick it up (it highlights), click another row's +-- grip to drop the held row just above it, or click the held grip to cancel. +-- +-- Interaction: a row is a static line by default. Click its text or the pencil +-- button to edit; press Enter or the ✓ button to commit back to the static +-- line. The coloured chip cycles the priority (a legend at the foot of the +-- panel maps each colour to its category). The ☐/☑ button toggles done, which +-- strikes the text through. A header trash button deletes every done row after +-- an inline confirmation strip (confirm/cancel) — the plugin UI has no dialog +-- primitive. No external commands are run. +-- +-- The bar widget (todo.luau) lights its glyph while the panel is open via the +-- shared "todo_open" state; it reads todo.json itself for the pending count. + +local PRIORITIES = { "important", "medium", "low" } +local RANK = { important = 1, medium = 2, low = 3 } +local COLORS = { important = "#e06c75", medium = "#e5c07b", low = "#98c379" } +local FILE_NAME = "todo.json" +local AUTOSAVE_IDLE_TICKS = 2 -- 1s panel ticks with no edits before a flush + +local items = {} -- array, ALWAYS in manual order (priority mode sorts a copy for display) +local nextId = 1 -- monotonic id source (identity only, not a sort key) +local folder = "" +local filePath = "" +local dirty = false -- unsaved inline text edits +local idleTicks = 0 +local editingId = nil -- id of the row currently in edit mode (at most one) +local loaded = false -- guard so an early save() can never truncate the file +local sortMode = "priority" -- "priority" (auto sort) or "manual" (grip reorder) +local grabbedId = nil -- id of the row "picked up" by its grip, awaiting a drop +local confirmingClear = false -- header trash pressed, awaiting confirm/cancel + +local render + +-- Per-row callbacks need distinct global names; the reconciler dispatches +-- callbacks by name only. getfenv() is the script environment lua_getglobal +-- reads from, so assigning into it defines the callback the host will find. +-- Keyed by the stable id, so a callback stays valid as rows reorder. +local env = getfenv() +local function rowCallback(prefix, id, fn) + local name = prefix .. "_" .. id + env[name] = fn + return name +end + +local function tr(key, args) + return noctalia.tr(key, args) +end + +local function isBlank(text) + return noctalia.string.trim(text or "") == "" +end + +local function todoFolder() + local dir = noctalia.getConfig("todo_folder") + if dir == nil or dir == "" then + dir = noctalia.expandPath("~/Documents/Todo") + else + dir = noctalia.expandPath(dir) + end + return (dir:gsub("/+$", "")) +end + +-- Overlay every character with U+0336 (combining long stroke) so a plain label +-- renders struck through — labels/buttons have no line-through prop. +local function strike(text) + if text == "" then + return "" + end + local out = {} + for _, code in utf8.codes(text) do + table.insert(out, utf8.char(code)) + table.insert(out, "\u{0336}") + end + return table.concat(out) +end + +local function normalizePriority(value) + return RANK[value] ~= nil and value or "medium" +end + +-- The rows to render, in display order. `items` itself is never reordered by +-- priority mode: it sorts a COPY (stable by priority via decorate-by-index, so +-- equal-priority rows keep their manual relative order). Keeping the sort out +-- of the model is what preserves the manual order across mode switches. +local function displayItems() + if sortMode ~= "priority" then + return items + end + local decorated = {} + for index, item in ipairs(items) do + decorated[index] = { item = item, index = index } + end + table.sort(decorated, function(a, b) + local ra, rb = RANK[a.item.priority], RANK[b.item.priority] + if ra ~= rb then + return ra < rb + end + return a.index < b.index -- stable: keep the manual within-priority order + end) + local sorted = {} + for index, entry in ipairs(decorated) do + sorted[index] = entry.item + end + return sorted +end + +local function findItem(id) + for _, item in ipairs(items) do + if item.id == id then + return item + end + end + return nil +end + +local function removeItem(id) + for i, item in ipairs(items) do + if item.id == id then + table.remove(items, i) + return true + end + end + return false +end + +local function load() + items = {} + nextId = 1 + sortMode = "priority" + local raw = noctalia.readFile(filePath) + if raw ~= nil and raw ~= "" then + local decoded = noctalia.json.decode(raw) + local list = nil + if type(decoded) == "table" then + -- Object form { version, sort, tasks }; a legacy plain array has no + -- `tasks` key and is read as-is (manual order, priority sort). + if decoded.tasks ~= nil then + if decoded.sort == "manual" or decoded.sort == "priority" then + sortMode = decoded.sort + end + list = decoded.tasks + else + list = decoded + end + end + if type(list) == "table" then + for _, entry in ipairs(list) do + if type(entry) == "table" then + local id = tonumber(entry.id) or nextId + table.insert(items, { + id = id, + text = type(entry.text) == "string" and entry.text or "", + priority = normalizePriority(entry.priority), + done = entry.done == true, + }) + if id >= nextId then + nextId = id + 1 + end + end + end + end + end + -- The on-disk order IS the manual order; priority mode sorts at render time. + loaded = true +end + +local function save() + if not loaded then + return -- never write before the first load reads what is on disk + end + -- Blank tasks are in-progress placeholders; they never reach disk. + local toStore = {} + for _, item in ipairs(items) do + if not isBlank(item.text) then + table.insert(toStore, item) + end + end + local encoded = noctalia.json.encode({ version = 2, sort = sortMode, tasks = toStore }, true) + if encoded == nil then + return + end + local ok, err = noctalia.writeFile(filePath, encoded) + if not ok then + noctalia.notifyError(tr("title"), err or tr("save_failed")) + return + end + dirty = false +end + +local function addItem() + local item = { id = nextId, text = "", priority = "medium", done = false } + nextId += 1 + -- Appended at the foot of the manual order; the priority view shows it at + -- the foot of its group. + table.insert(items, item) + editingId = item.id -- new task opens straight into edit mode + render() +end + +local function deleteItem(id) + removeItem(id) + if editingId == id then + editingId = nil + end + if grabbedId == id then + grabbedId = nil + end + save() + render() +end + +local function enterEdit(id) + -- Leaving a still-blank row behind (e.g. a just-added task) would strand an + -- empty line; drop it as we move focus elsewhere. + if editingId ~= nil and editingId ~= id then + local prev = findItem(editingId) + if prev ~= nil and isBlank(prev.text) then + removeItem(editingId) + end + end + editingId = id + render() +end + +local function commitEdit(id, value) + local item = findItem(id) + if item == nil then + return + end + item.text = value + editingId = nil + if isBlank(item.text) then + removeItem(id) -- committing a blank task discards it + end + save() + render() +end + +local function toggleDone(id) + local item = findItem(id) + if item ~= nil then + item.done = not item.done + save() + render() + end +end + +local function cyclePriority(id) + local item = findItem(id) + if item ~= nil then + -- important → medium → low → important. The manual position is + -- untouched; the priority view re-sorts on render. + item.priority = PRIORITIES[(RANK[item.priority] % #PRIORITIES) + 1] + save() + render() + end +end + +-- Switch ordering mode. Only the `sort` choice is persisted — the task array +-- is never rewritten, so the manual order survives any number of round trips +-- through priority mode. Any half-finished grab is dropped. +local function setSortMode(mode) + if mode ~= "manual" and mode ~= "priority" then + return + end + sortMode = mode + grabbedId = nil + save() + render() +end + +-- Move the grabbed row to sit just above `targetId` (manual reorder via grips). +-- A drop onto the held row itself, or onto a vanished target, simply cancels. +local function dropGrabbedOn(targetId) + if grabbedId == nil or grabbedId == targetId then + grabbedId = nil + render() + return + end + local grabbed = nil + for i, item in ipairs(items) do + if item.id == grabbedId then + grabbed = table.remove(items, i) + break + end + end + grabbedId = nil + if grabbed == nil then + render() + return + end + local targetIndex = #items + 1 + for i, item in ipairs(items) do + if item.id == targetId then + targetIndex = i + break + end + end + table.insert(items, targetIndex, grabbed) + save() + render() +end + +local function doneCount() + local n = 0 + for _, item in ipairs(items) do + if item.done then + n += 1 + end + end + return n +end + +-- Remove every done row (the header trash, after confirmation). Editing or +-- grab state pointing at a removed row is dropped with it. +local function clearDone() + local kept = {} + for _, item in ipairs(items) do + if not item.done then + table.insert(kept, item) + end + end + if #kept ~= #items then + items = kept + if editingId ~= nil and findItem(editingId) == nil then + editingId = nil + end + if grabbedId ~= nil and findItem(grabbedId) == nil then + grabbedId = nil + end + save() + end + confirmingClear = false + render() +end + +local function taskRow(item) + local id = item.id + local editing = editingId == id + local grabbed = grabbedId == id + + -- Manual mode only: a ☰ grip that "picks up" the row, or drops the held one + -- here. Same glyph noctalia's own bar reorder uses ("menu-2"); it lights up + -- (primary) while this row is the one being held. + local grip = nil + if sortMode == "manual" then + grip = ui.button({ + key = "grip-" .. id .. (grabbed and "-on" or ""), + glyph = "menu-2", + variant = grabbed and "primary" or "ghost", + tooltip = tr(grabbed and "tip_grip_drop" or "tip_grip"), + onClick = rowCallback("todoGrip", id, function() + if grabbedId == nil then + grabbedId = id + render() + else + dropGrabbedOn(id) + end + end), + }) + end + + local chip = ui.box({ + -- priority in the key so the retained box picks up the new fill colour + key = "chip-" .. id .. "-" .. item.priority, + width = 16, + height = 16, + radius = 4, + fill = COLORS[item.priority], + onClick = rowCallback("todoPrio", id, function() + cyclePriority(id) + end), + }) + local children = {} + if grip ~= nil then + table.insert(children, grip) + end + table.insert(children, chip) + + if editing then + table.insert(children, ui.input({ + key = "text-" .. id, + value = item.text, + placeholder = tr("placeholder"), + focus = true, + flexGrow = 1, + onChange = rowCallback("todoText", id, function(value) + item.text = value + dirty = true + idleTicks = 0 + end), + onSubmit = rowCallback("todoSubmit", id, function(value) + commitEdit(id, value) + end), + })) + -- ✓ commits the edit, mirroring Enter. + table.insert(children, ui.button({ + glyph = "check", + variant = "primary", + tooltip = tr("tip_commit"), + onClick = rowCallback("todoOk", id, function() + commitEdit(id, item.text) + end), + })) + else + -- Static text; clicking it re-opens the editor ("press on the text"). + table.insert(children, ui.button({ + key = "view-" .. id, + text = item.done and strike(item.text) or item.text, + variant = "ghost", + contentAlign = "start", + flexGrow = 1, + onClick = rowCallback("todoEdit", id, function() + enterEdit(id) + end), + })) + -- Done toggle: strikes the text through. + table.insert(children, ui.button({ + glyph = item.done and "square-check" or "square", + variant = "ghost", + tooltip = tr(item.done and "tip_undone" or "tip_done"), + onClick = rowCallback("todoDone", id, function() + toggleDone(id) + end), + })) + -- Explicit edit affordance next to the row. + table.insert(children, ui.button({ + glyph = "pencil", + variant = "ghost", + tooltip = tr("tip_edit"), + onClick = rowCallback("todoPencil", id, function() + enterEdit(id) + end), + })) + end + + table.insert(children, ui.button({ + glyph = "trash", + variant = "ghost", + tooltip = tr("tip_delete"), + onClick = rowCallback("todoDel", id, function() + deleteItem(id) + end), + })) + + return ui.row({ + -- edit/done/mode/grab state flips the row's controls; key it to recreate cleanly + key = "row-" + .. id + .. (editing and "-edit" or "-view") + .. (item.done and "-done" or "") + .. (sortMode == "manual" and "-m" or "") + .. (grabbed and "-grab" or ""), + gap = 8, + align = "center", + }, children) +end + +-- A footer legend mapping each chip colour to its category. +local function legendEntry(priority) + return ui.row({ gap = 6, align = "center" }, { + ui.box({ width = 12, height = 12, radius = 3, fill = COLORS[priority] }), + ui.label({ text = tr("prio_" .. priority), fontSize = 11, color = "on_surface_variant" }), + }) +end + +render = function() + -- Ordering toggle: shows the current mode and flips it. "menu-2" (the grip + -- glyph) for manual, "palette" for the colour/priority sort. + local sortToggle = ui.button({ + key = "header-sort-" .. sortMode, + glyph = sortMode == "manual" and "menu-2" or "palette", + text = sortMode == "manual" and tr("sort_manual") or tr("sort_priority"), + variant = "ghost", + tooltip = tr("tip_sort"), + onClick = "onSortToggle", + }) + + -- With nothing done the trash has nothing to clear; keep it visible but + -- disabled, and fold away a confirmation left open while the last done + -- row was toggled back. + local done = doneCount() + if done == 0 then + confirmingClear = false + end + + local header = ui.row({ align = "center", gap = 8 }, { + ui.label({ text = tr("title"), fontSize = 16, fontWeight = "bold", color = "on_surface", flexGrow = 1 }), + sortToggle, + ui.button({ + key = "header-clear-done" .. (done == 0 and "-off" or ""), + glyph = "trash", + variant = "ghost", + enabled = done > 0, + tooltip = tr("tip_clear_done"), + onClick = "onClearDone", + }), + ui.button({ key = "header-add", glyph = "plus", variant = "primary", tooltip = tr("tip_add"), onClick = "onAdd" }), + ui.button({ key = "header-close", glyph = "close", variant = "ghost", tooltip = tr("tip_close"), onClick = "onClosePanel" }), + }) + + -- Confirmation strip for the header trash: the question plus an explicit + -- destructive confirm and a cancel, in place of a modal (the plugin UI has + -- no dialog primitive). + local confirmStrip = nil + if confirmingClear then + confirmStrip = ui.row({ key = "confirm-clear", gap = 8, align = "center" }, { + ui.label({ text = tr("clear_done_confirm"), color = "on_surface", flexGrow = 1 }), + ui.button({ text = tr("clear_done_yes"), variant = "destructive", onClick = "onClearDoneConfirm" }), + ui.button({ text = tr("clear_done_no"), variant = "ghost", onClick = "onClearDoneCancel" }), + }) + end + + local legend = ui.column({ gap = 8 }, { + ui.separator({}), + ui.row({ gap = 16, align = "center", justify = "center" }, { + legendEntry("important"), + legendEntry("medium"), + legendEntry("low"), + }), + }) + + local body + if #items == 0 then + body = ui.column({ flexGrow = 1, align = "center", justify = "center" }, { + ui.label({ text = tr("empty"), color = "on_surface_variant" }), + }) + else + local rows = {} + for _, item in ipairs(displayItems()) do + table.insert(rows, taskRow(item)) + end + body = ui.scroll({ flexGrow = 1, gap = 6 }, rows) + end + + local parts = { header } + if confirmStrip ~= nil then + table.insert(parts, confirmStrip) + end + table.insert(parts, body) + table.insert(parts, legend) + panel.render(ui.column({ flexGrow = 1, gap = 12, align = "stretch" }, parts)) +end + +function onOpen(_context) + folder = todoFolder() + filePath = folder .. "/" .. FILE_NAME + local ok, err = noctalia.mkdirAll(folder) + if not ok then + noctalia.notifyError(tr("title"), err or "") + end + load() + editingId = nil + grabbedId = nil + confirmingClear = false + dirty = false + idleTicks = 0 + panel.setWantsSecondTicks(true) + noctalia.state.set("todo_open", true) + render() +end + +function onClose() + editingId = nil + grabbedId = nil + confirmingClear = false + if dirty then + save() + end + noctalia.state.set("todo_open", false) +end + +function onConfigChanged() + if dirty then + save() + end + folder = todoFolder() + filePath = folder .. "/" .. FILE_NAME + noctalia.mkdirAll(folder) + editingId = nil + grabbedId = nil + confirmingClear = false + load() + render() +end + +function update() + if dirty then + idleTicks += 1 + if idleTicks >= AUTOSAVE_IDLE_TICKS then + save() + end + end +end + +function onAdd() + addItem() +end + +function onSortToggle() + setSortMode(sortMode == "manual" and "priority" or "manual") +end + +function onClearDone() + confirmingClear = true + render() +end + +function onClearDoneConfirm() + clearDone() +end + +function onClearDoneCancel() + confirmingClear = false + render() +end + +function onClosePanel() + panel.close() +end diff --git a/todo/plugin.toml b/todo/plugin.toml new file mode 100644 index 0000000..893a55f --- /dev/null +++ b/todo/plugin.toml @@ -0,0 +1,45 @@ +# To Do — a prioritised task list on the bar. Click the glyph to toggle a panel +# of editable task rows: add with +, tick to complete (the text is struck +# through), delete, and click each row's colour chip to cycle its priority +# (important → medium → low). A header toggle switches ordering between priority +# (auto-sorted) and manual, where a ☰ grip on each row reorders it by clicking. +# The whole list is a single JSON file in the configured folder; no external +# commands are run. + +id = "nightwatch75/todo" +name = "To Do" +version = "0.0.7" +min_noctalia = "5.0.0" +author = "nightwatch75" +license = "MIT" +dependencies = [] +tags = ["bar", "panel", "productivity"] +icon = "checklist" +description = "A prioritised to-do list in a bar panel: editable tasks with low/medium/important colour chips, a done/to-do toggle that strikes completed text through, and ordering that switches between priority-sorted and manual (drag-free ☰ grip reorder)." + +# Plugin-level setting: the folder holding the task file, shared by the panel +# (reads/writes it) and the bar widget (reads it for the pending count). +[[setting]] +key = "todo_folder" +type = "folder" +label_key = "settings.todo_folder.label" +description_key = "settings.todo_folder.description" + +[[panel]] +id = "panel" +entry = "panel.luau" +width = 400 +height = 460 +placement = "attached" +open_near_click = true + +[[widget]] +id = "todo" +entry = "todo.luau" + + [[widget.setting]] + key = "glyph" + type = "glyph" + label_key = "settings.glyph.label" + description_key = "settings.glyph.description" + default = "checklist" diff --git a/todo/thumbnail.webp b/todo/thumbnail.webp new file mode 100644 index 0000000000000000000000000000000000000000..bf5a6819eca86c8e225ef653adecf769f1a4f4bc GIT binary patch literal 57206 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%0ARlnV^zrN^jWZqH)}4N{<@mX} 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 literal 0 HcmV?d00001 diff --git a/todo/todo.luau b/todo/todo.luau new file mode 100644 index 0000000..a127e4d --- /dev/null +++ b/todo/todo.luau @@ -0,0 +1,73 @@ +--!nonstrict +-- To Do — bar widget that toggles the task panel. +-- +-- The glyph is configurable (widget setting). It lights up while the panel is +-- open (shared "todo_open" state, published by panel.luau) and its tooltip +-- shows how many tasks are still to do. The count is read straight from +-- todo.json, so it is correct before the panel is ever opened and reflects +-- edits made to the file outside noctalia. + +local PANEL_ID = "nightwatch75/todo:panel" +local FILE_NAME = "todo.json" + +local open = false +local pending = 0 + +local function todoFile() + local dir = noctalia.getConfig("todo_folder") + if dir == nil or dir == "" then + dir = noctalia.expandPath("~/Documents/Todo") + else + dir = noctalia.expandPath(dir) + end + return (dir:gsub("/+$", "")) .. "/" .. FILE_NAME +end + +local function pendingCount() + local raw = noctalia.readFile(todoFile()) + if raw == nil or raw == "" then + return 0 + end + local decoded = noctalia.json.decode(raw) + if type(decoded) ~= "table" then + return 0 + end + -- Object form { version, sort, tasks }; a legacy plain array is read as-is. + local list = decoded.tasks ~= nil and decoded.tasks or decoded + if type(list) ~= "table" then + return 0 + end + local n = 0 + for _, entry in ipairs(list) do + if type(entry) == "table" and entry.done ~= true then + n += 1 + end + end + return n +end + +local function render() + barWidget.setGlyph(noctalia.getConfig("glyph")) + barWidget.setGlyphColor(open and "primary" or "on_surface") + barWidget.setTooltip(noctalia.tr("tooltip", { count = pending })) +end + +noctalia.state.watch("todo_open", function(value) + open = value == true + render() +end) + +-- Periodic re-read keeps the pending count and glyph in sync with edits and +-- setting changes. +function update() + pending = pendingCount() + render() +end + +function onClick() + noctalia.togglePanel(PANEL_ID) +end + +noctalia.setUpdateInterval(2000) +pending = pendingCount() +render() diff --git a/todo/translations/en.json b/todo/translations/en.json new file mode 100644 index 0000000..2af0fdd --- /dev/null +++ b/todo/translations/en.json @@ -0,0 +1,30 @@ +{ + "title": "To Do", + "empty": "No tasks yet — add one with +", + "placeholder": "New task…", + "tooltip": "To Do — {count} to do", + "save_failed": "Failed to save the task list", + "prio_low": "Low", + "prio_medium": "Medium", + "prio_important": "Important", + "sort_priority": "Priority", + "sort_manual": "Manual", + "clear_done_confirm": "Delete all done entries?", + "clear_done_yes": "Delete", + "clear_done_no": "Cancel", + "tip_sort": "Switch ordering mode", + "tip_clear_done": "Delete all done tasks", + "tip_add": "Add a task", + "tip_close": "Close", + "tip_grip": "Reorder — click to pick this row up", + "tip_grip_drop": "Click another grip to drop here, or this one to cancel", + "tip_commit": "Save (Enter)", + "tip_done": "Mark as done", + "tip_undone": "Mark as to do", + "tip_edit": "Edit", + "tip_delete": "Delete task", + "settings.todo_folder.label": "To Do folder", + "settings.todo_folder.description": "Folder holding the task list (todo.json). Defaults to ~/Documents/Todo.", + "settings.glyph.label": "Bar glyph", + "settings.glyph.description": "The glyph shown for the To Do widget on the bar." +}