dblclick for new note; immediately-cancellable notes

dev
brian 4 years ago
parent 6ec471c82a
commit 3e64bca676

@ -1,5 +1,6 @@
import Note from './Note.js'; import Note from './Note.js';
import { import {
preventDblClickSelection,
new_note_handler, new_note_handler,
new_note_by_dblclick_handler, new_note_by_dblclick_handler,
search_term_change_handler, search_term_change_handler,
@ -67,7 +68,7 @@ function App(vnode_init){
]) ])
]), ]),
m('.main', {key: 'main'}, [ m('.main', {key: 'main'}, [
m('.notes', {ondblclick: o(new_note_by_dblclick_handler)}, s.notes.map(note_state => m('.notes', {ondblclick: o(new_note_by_dblclick_handler), onmousedown:preventDblClickSelection}, s.notes.map(note_state =>
m(Note, {state:s, note_state, dispatch, key: note_state.note_id}) m(Note, {state:s, note_state, dispatch, key: note_state.note_id})
)) ))
]) ])

@ -11,7 +11,7 @@ function Note(vnode_init){
return m('.note', [ return m('.note', [
m('textarea', {key: 'textarea', onchange: text_change_handler.bind(null, note_state, dispatch), oncreate: is_focused?({dom})=>{ dom.focus(); delete note_state.is_focused; }:null }, note_state.temp_text), m('textarea', {key: 'textarea', onchange: text_change_handler.bind(null, note_state, dispatch), oncreate: is_focused?({dom})=>{ dom.focus(); delete note_state.is_focused; }:null }, note_state.temp_text),
m('.buttons', {key: 'editing-buttons'}, [ m('.buttons', {key: 'editing-buttons'}, [
m('button', {key: 'cancel-button', onclick: cancel_handler.bind(null, note_state, dispatch) }, 'Cancel'), m('button', {key: 'cancel-button', onclick: cancel_handler.bind(null, state, note_state, dispatch) }, 'Cancel'),
m('button', {key: 'save-button', onclick: save_handler.bind(null, note_state, dispatch) }, 'Save') m('button', {key: 'save-button', onclick: save_handler.bind(null, note_state, dispatch) }, 'Save')
]) ])
]); ]);

@ -1,6 +1,12 @@
import nanoid from '../nanoid.min.js'; import nanoid from '../nanoid.min.js';
import api from '../api.js'; import api from '../api.js';
const preventDblClickSelection = function(e){
// as per [https://stackoverflow.com/a/43321596]
if(e.detail>1){
e.preventDefault();
}
}
const load_notes = function(state, dispatch){ const load_notes = function(state, dispatch){
api.post('/load-notes', {bin_id: state.bin_id}) api.post('/load-notes', {bin_id: state.bin_id})
.then(res=>{ .then(res=>{
@ -88,7 +94,8 @@ const choose_bin_handler = function(state, dispatch, bin_id){
}); });
}; };
export {new_note_handler, export {preventDblClickSelection,
new_note_handler,
new_note_by_dblclick_handler, new_note_by_dblclick_handler,
search_term_change_handler, search_term_change_handler,
sorting_change_handler, sorting_change_handler,

@ -3,8 +3,14 @@ import api from '../api.js';
const edit_handler = function(note_state, dispatch){ const edit_handler = function(note_state, dispatch){
dispatch('update-note-editing', {id: note_state.note_id, is_editing: true}); dispatch('update-note-editing', {id: note_state.note_id, is_editing: true});
}; };
const cancel_handler = function(note_state, dispatch){ const cancel_handler = function(state, note_state, dispatch){
// TODO: this `if` may cause glitches; keep in mind
if(note_state.is_new===true){
dispatch('immediately-cancel-note', note_state.note_id);
}
else{
dispatch('update-note-editing', {id: note_state.note_id, is_editing: false}); dispatch('update-note-editing', {id: note_state.note_id, is_editing: false});
}
}; };
const text_change_handler = function(note_state, dispatch, e){ const text_change_handler = function(note_state, dispatch, e){
note_state.temp_text = e.target.value; note_state.temp_text = e.target.value;

@ -78,6 +78,11 @@ const refAll = function(s, o, key, new_model_ids){
This routine would need to be called for state.notes, which contains refs of the form: `state.notes[n].note_id` This routine would need to be called for state.notes, which contains refs of the form: `state.notes[n].note_id`
*/ */
// TODO: doesn't update anything that references the deleted record; results in dangling pointers:
const disintegrate = function(s, id){
delete s.db[id];
};
function addToBinListIfLoggedIn(state){ function addToBinListIfLoggedIn(state){
const s = state; const s = state;
// if user is logged in: // if user is logged in:
@ -98,9 +103,10 @@ const reducer = handleActions({
'bin-loaded': (s, bin) => { i(s,bin); ref(s,s,'bin_id',bin.id); s.temp_bin_name=bin.name; }, 'bin-loaded': (s, bin) => { i(s,bin); ref(s,s,'bin_id',bin.id); s.temp_bin_name=bin.name; },
'update-search-term': (s, search_term) => { s.search_term=search_term; }, 'update-search-term': (s, search_term) => { s.search_term=search_term; },
'update-search-results': (s, _notes) => { integrateAll(s,s.notes,'note_id',_notes); s.notes =_notes.map(n=>({is_editing: false, temp_text: '', bin_id: s.bin_id, note_id:n.id})); }, 'update-search-results': (s, _notes) => { integrateAll(s,s.notes,'note_id',_notes); s.notes =_notes.map(n=>({is_editing: false, temp_text: '', bin_id: s.bin_id, note_id:n.id})); },
'add-note': (s, {id, date}) => { i(s, {id: id, text: '', modified: date}); s.notes.unshift({is_editing: true, temp_text: '', bin_id: s.bin_id, is_focused:true, note_id: id}); }, 'add-note': (s, {id, date}) => { i(s, {id: id, text: '', modified: date}); s.notes.unshift({is_editing: true, temp_text: '', bin_id: s.bin_id, is_focused:true, is_new: true, note_id: id}); },
'notes-loaded': (s, _notes) => { integrateAll(s,_notes); s.notes = _notes.map(n=>({is_editing: false, temp_text: n.text, bin_id: s.bin_id, note_id:n.id})); }, 'notes-loaded': (s, _notes) => { integrateAll(s,_notes); s.notes = _notes.map(n=>({is_editing: false, temp_text: n.text, bin_id: s.bin_id, note_id:n.id})); },
'update-note-text': (s, {id, text}) => { const note_s=s.notes.find(n=>n.note_id===id); s.db[note_s.note_id].model.text=text; }, // updates underlying note text (i.e. the "model", not the app note_state) "in the background" (e.g. from a server-pushed update), regardless of whether it's being edited; "save" is a separate action, below 'immediately-cancel-note': (s, note_id) => { disintegrate(s,note_id); s.notes.splice(s.notes.findIndex(n=>n.note_id===note_id), 1); },
'update-note-text': (s, {id, text}) => { const note_s=s.notes.find(n=>n.note_id===id); note_s.is_new=false; s.db[note_s.note_id].model.text=text; }, // updates underlying note text (i.e. the "model", not the app note_state) "in the background" (e.g. from a server-pushed update), regardless of whether it's being edited; "save" is a separate action, below
'update-note-editing': (s, {id, is_editing}) => { const note_s=s.notes.find(n=>n.note_id===id); note_s.is_editing=is_editing; note_s.temp_text=s.db[note_s.note_id].model.text; }, 'update-note-editing': (s, {id, is_editing}) => { const note_s=s.notes.find(n=>n.note_id===id); note_s.is_editing=is_editing; note_s.temp_text=s.db[note_s.note_id].model.text; },
'save-note-edit': (s, {id, text}) => { const note_s=s.notes.find(n=>n.note_id===id); s.db[note_s.note_id].model.text=text; note_s.temp_text=text; note_s.is_editing=false; }, 'save-note-edit': (s, {id, text}) => { const note_s=s.notes.find(n=>n.note_id===id); s.db[note_s.note_id].model.text=text; note_s.temp_text=text; note_s.is_editing=false; },
'update-sorting': (s, sorting) => { s.sorting=sorting; }, 'update-sorting': (s, sorting) => { s.sorting=sorting; },

Loading…
Cancel
Save