1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-11-24 08:12:24 +02:00

Desktop: Toggle todo checkbox using SPACE key

This commit is contained in:
Laurent Cozic 2019-01-26 15:33:45 +00:00
parent fef176eb96
commit f62bbfe286
3 changed files with 58 additions and 16 deletions

View File

@ -365,22 +365,7 @@ class NoteListComponent extends React.Component {
this.itemListRef.current.makeItemIndexVisible(noteIndex);
// - We need to focus the item manually otherwise focus might be lost when the
// list is scrolled and items within it are being rebuilt.
// - We need to use an interval because when leaving the arrow pressed, the rendering
// of items might lag behind and so the ref is not yet available at this point.
if (!this.itemAnchorRef(newSelectedNote.id)) {
if (this.focusItemIID_) clearInterval(this.focusItemIID_);
this.focusItemIID_ = setInterval(() => {
if (this.itemAnchorRef(newSelectedNote.id)) {
this.itemAnchorRef(newSelectedNote.id).focus();
clearInterval(this.focusItemIID_)
this.focusItemIID_ = null;
}
}, 10);
} else {
this.itemAnchorRef(newSelectedNote.id).focus();
}
this.focusNoteId_(newSelectedNote.id);
event.preventDefault();
}
@ -389,6 +374,40 @@ class NoteListComponent extends React.Component {
event.preventDefault();
await this.confirmDeleteNotes(noteIds);
}
if (noteIds.length && keyCode === 32) { // SPACE
event.preventDefault();
const notes = BaseModel.modelsByIds(this.props.notes, noteIds);
const todos = notes.filter(n => !!n.is_todo);
if (!todos.length) return;
for (let i = 0; i < todos.length; i++) {
const toggledTodo = Note.toggleTodoCompleted(todos[i]);
await Note.save(toggledTodo);
}
this.focusNoteId_(todos[0].id);
}
}
focusNoteId_(noteId) {
// - We need to focus the item manually otherwise focus might be lost when the
// list is scrolled and items within it are being rebuilt.
// - We need to use an interval because when leaving the arrow pressed, the rendering
// of items might lag behind and so the ref is not yet available at this point.
if (!this.itemAnchorRef(noteId)) {
if (this.focusItemIID_) clearInterval(this.focusItemIID_);
this.focusItemIID_ = setInterval(() => {
if (this.itemAnchorRef(noteId)) {
this.itemAnchorRef(noteId).focus();
clearInterval(this.focusItemIID_)
this.focusItemIID_ = null;
}
}, 10);
} else {
this.itemAnchorRef(noteId).focus();
}
}
componentWillUnmount() {

View File

@ -51,6 +51,16 @@ class BaseModel {
return -1;
}
static modelsByIds(items, ids) {
const output = [];
for (let i = 0; i < items.length; i++) {
if (ids.indexOf(items[i].id) >= 0) {
output.push(items[i]);
}
}
return output;
}
// Prefer the use of this function to compare IDs as it handles the case where
// one ID is null and the other is "", in which case they are actually considered to be the same.
static idsEqual(id1, id2) {

View File

@ -474,6 +474,19 @@ class Note extends BaseItem {
return this.changeNoteType(note, !!note.is_todo ? 'note' : 'todo');
}
static toggleTodoCompleted(note) {
if (!('todo_completed' in note)) throw new Error('Missing "todo_completed" property');
note = Object.assign({}, note);
if (note.todo_completed) {
note.todo_completed = 0;
} else {
note.todo_completed = Date.now();
}
return note;
}
static async duplicate(noteId, options = null) {
const changes = options && options.changes;
const uniqueTitle = options && options.uniqueTitle;