Add a checklist button next to the + button in the memo composer #6056
Closed
vfontanela
started this conversation in
Ideas
Replies: 1 comment 1 reply
|
@vfontanela thanks for bring this up. We'll get a formatting toolbar that contains a task item insert action. Let's waiting for next release.
|
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment

Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Typing /todo on a phone to create a task list works, but it is a little annoying for quick notes, shopping lists, or simple checklists.
Memos already supports task lists very well once the checklist is started:
typing /todo inserts - [ ]
pressing Enter continues the checklist correctly
checking/unchecking items already works
So I think it would be great to expose this existing behavior as a small checklist button next to the existing + button in the memo composer.
This is not a request for a full task-management system. It is only a small UI improvement for the existing task-list feature and the existing /todo command.
I tested this using Memos’ built-in Settings → System → Additional Script, and it works on both desktop and mobile. Since the script is stored in Memos itself, it also persists across devices after logging in.
The proof of concept below adds a ☑ button next to the + button. When clicked, it inserts - [ ] at the current cursor position and focuses the editor. It also hides the button when a sidebar, modal, or overlay covers the composer.
`
(() => {
const ID = "vf-memos-checklist-button";
function isVisible(el) {
if (!el) return false;
const r = el.getBoundingClientRect();
return r.width > 0 && r.height > 0;
}
function isEditable(el) {
return (
el &&
(
el.tagName === "TEXTAREA" ||
el.tagName === "INPUT" ||
el.isContentEditable
)
);
}
function isTitleField(el) {
const ph = (el.getAttribute("placeholder") || "").toLowerCase();
return (
ph.includes("título") ||
ph.includes("titulo") ||
ph.includes("title")
);
}
let lastEditor = null;
function rememberEditor(el) {
if (isEditable(el) && !isTitleField(el)) {
lastEditor = el;
}
}
document.addEventListener("focusin", e => rememberEditor(e.target), true);
document.addEventListener("click", e => rememberEditor(e.target), true);
document.addEventListener("keyup", e => rememberEditor(e.target), true);
function findEditor() {
if (isEditable(lastEditor) && !isTitleField(lastEditor)) {
return lastEditor;
}
}
function setNativeValue(el, value) {
const proto =
el.tagName === "TEXTAREA"
? HTMLTextAreaElement.prototype
: HTMLInputElement.prototype;
}
function insertTodo() {
const el = findEditor();
}
function findPlusButton() {
const editor = findEditor();
if (!editor) return null;
}
function makeButton() {
const btn = document.createElement("button");
btn.id = ID;
btn.type = "button";
btn.textContent = "☑";
btn.title = "Insert checklist";
btn.setAttribute("aria-label", "Insert checklist");
}
function isElementReallyOnTop(el) {
if (!el) return false;
}
function positionButton() {
let btn = document.getElementById(ID);
if (!btn) btn = makeButton();
}
const observer = new MutationObserver(positionButton);
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true
});
window.addEventListener("resize", positionButton);
window.addEventListener("scroll", positionButton, true);
setInterval(positionButton, 700);
positionButton();
})();
`
All reactions