diff --git a/nginx/public_html/App.js b/nginx/public_html/App.js
index 0e6b8a0..e87f318 100644
--- a/nginx/public_html/App.js
+++ b/nginx/public_html/App.js
@@ -1,5 +1,6 @@
import Note from './Note.js';
import {
+ preventDblClickSelection,
new_note_handler,
new_note_by_dblclick_handler,
search_term_change_handler,
@@ -67,7 +68,7 @@ function App(vnode_init){
])
]),
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})
))
])
diff --git a/nginx/public_html/Note.js b/nginx/public_html/Note.js
index 7e9e779..9dc39ba 100644
--- a/nginx/public_html/Note.js
+++ b/nginx/public_html/Note.js
@@ -11,7 +11,7 @@ function Note(vnode_init){
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('.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')
])
]);
diff --git a/nginx/public_html/handlers/App.js b/nginx/public_html/handlers/App.js
index 3f53a9b..ea034bc 100644
--- a/nginx/public_html/handlers/App.js
+++ b/nginx/public_html/handlers/App.js
@@ -1,6 +1,12 @@
import nanoid from '../nanoid.min.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){
api.post('/load-notes', {bin_id: state.bin_id})
.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,
search_term_change_handler,
sorting_change_handler,
diff --git a/nginx/public_html/handlers/Note.js b/nginx/public_html/handlers/Note.js
index 8db6e58..0842c73 100644
--- a/nginx/public_html/handlers/Note.js
+++ b/nginx/public_html/handlers/Note.js
@@ -3,8 +3,14 @@ import api from '../api.js';
const edit_handler = function(note_state, dispatch){
dispatch('update-note-editing', {id: note_state.note_id, is_editing: true});
};
-const cancel_handler = function(note_state, dispatch){
- dispatch('update-note-editing', {id: note_state.note_id, is_editing: false});
+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});
+ }
};
const text_change_handler = function(note_state, dispatch, e){
note_state.temp_text = e.target.value;
diff --git a/nginx/public_html/index.js b/nginx/public_html/index.js
index 376d6c4..11c3d91 100644
--- a/nginx/public_html/index.js
+++ b/nginx/public_html/index.js
@@ -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`
*/
+// 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){
const s = state;
// 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; },
'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})); },
- '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})); },
- '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; },
'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; },