WIP on buttons, simplify, remove some event dispatch

- I made the buttons work like GitHub comment-on-issue buttons
before typing:  "Close Note" / "Comment" (disabled)
after typing:   "Close and Comment" / "Comment" (enabled)

- I removed a bunch of the event dispatches.  These are useful for sending
events to listeners/observers outside of the module.  In this case I think
we can handle most of the things from within the uiNoteEditor.  We can still
dispatch an 'update' event so that modeSelectNote can reselect and redraw
the note after some change happens to it.

TODO - make the buttons work / check the OSM API stuff.
This commit is contained in:
Bryan Housel
2018-07-11 23:10:01 -04:00
parent 3454753bf6
commit 91add0c33e
6 changed files with 159 additions and 220 deletions
+1 -1
View File
@@ -76,7 +76,7 @@
.note-header-label {
background-color: #f6f6f6;
padding: 0 10px;
padding: 0 15px;
flex: 1 1 100%;
font-size: 14px;
font-weight: bold;
+4 -6
View File
@@ -616,15 +616,13 @@ en:
anonymous: anonymous
closed: "(Closed)"
commentTitle: Comments
close: Resolve
reopen: Reopen
newComment: New Comment
inputPlaceholder: Enter a comment to share with other users.
close: Close Note
open: Reopen Note
comment: Comment
commentClose: Comment & Resolve
commentReopen: Comment & Reopen
save: Save comment
cancel: Cancel
close_comment: Close and Comment
open_comment: Reopen and Comment
help:
title: Help
key: H
+4 -6
View File
@@ -749,15 +749,13 @@
"anonymous": "anonymous",
"closed": "(Closed)",
"commentTitle": "Comments",
"close": "Resolve",
"reopen": "Reopen",
"newComment": "New Comment",
"inputPlaceholder": "Enter a comment to share with other users.",
"close": "Close Note",
"open": "Reopen Note",
"comment": "Comment",
"commentClose": "Comment & Resolve",
"commentReopen": "Comment & Reopen",
"save": "Save comment",
"cancel": "Cancel"
"close_comment": "Close and Comment",
"open_comment": "Reopen and Comment"
},
"help": {
"title": "Help",
+1 -1
View File
@@ -25,7 +25,7 @@ export function modeSelectNote(context, selectedNoteID) {
var osm = services.osm;
var keybinding = d3_keybinding('select-note');
var noteEditor = uiNoteEditor(context)
.on('updateNote', function() {
.on('update', function() {
// .call(drawNotes); // TODO: update and redraw notes
var note = checkSelectedID();
if (!note) return;
+1 -5
View File
@@ -1,7 +1,4 @@
import {
event as d3_event,
select as d3_select
} from 'd3-selection';
import { select as d3_select } from 'd3-selection';
import { t } from '../util/locale';
import { svgIcon } from '../svg';
@@ -10,7 +7,6 @@ import { utilDetect } from '../util/detect';
export function uiNoteComments() {
var commentLimit = 600; // add a "more" link to comments longer than this length
var _note;
+148 -201
View File
@@ -6,7 +6,6 @@ import {
} from 'd3-selection';
import { t } from '../util/locale';
import { svgIcon } from '../svg';
import { services } from '../services';
import { uiNoteComments } from './note_comments';
@@ -17,213 +16,15 @@ import {
utilRebind
} from '../util';
import { utilDetect } from '../util/detect';
import { modeBrowse } from '../modes';
export function uiNoteEditor(context) {
// TODO: use 'toggleNote' and 'saveNote' to add 'thank you' warning to the sidebar
var dispatch = d3_dispatch('change', 'cancel', 'save', 'modifiedInput', 'updateNote', 'toggleNote', 'saveNote');
var dispatch = d3_dispatch('update');
var noteHeader = uiNoteHeader();
var noteComments = uiNoteComments();
var _inputValue;
var _newComment;
var _note;
var _modified;
function noteEditor(selection) {
render(selection);
}
function cancel() {
_newComment = false;
context.selectedNoteID(null);
context.enter(modeBrowse(context));
}
function save(updateFunction) {
var osm = context.connection();
if (!osm) {
context.enter(modeBrowse(context));
return;
}
// If user somehow got logged out mid-save, try to reauthenticate..
// This can happen if they were logged in from before, but the tokens are no longer valid.
if (!osm.authenticated()) {
// TODO: dispatch 'notAuthenticated' to give warning
osm.authenticate(function(err) {
if (err) { // quit save mode..
context.enter(modeBrowse(context));
return;
} else {
save(updateFunction); // continue where we left off..
}
});
return;
}
function parseResults(results) { // TODO: simplify result parsing
dispatch.call('change', results);
// call success
if (results) {
success(results);
}
// otherwise, call failure
else {
failure(results);
}
}
function success(results) {
console.log('success!', results); // TODO: handle success
dispatch.apply('updateNote');
}
function failure(results) { // TODO: handle failure & errors
console.log('failure!', results);
}
updateFunction(parseResults);
}
function toggleNoteStatus(parseResults) {
if (!_note || !_note.status || !context.selectedNoteID) return;
services.osm.toggleNoteStatus(_note, _inputValue, parseResults);
}
function addNoteComment(parseResults) {
if (!_note || !_note.status || !context.selectedNoteID) return;
services.osm.addNoteComment(_note, _inputValue, parseResults);
}
function newComment(selection) {
if (!context.selectedNoteID()) return;
// New Comment
var saveSection = selection.selectAll('.save-section')
.data([0]);
saveSection = saveSection.enter()
.append('div')
.attr('class','save-section cf')
.merge(saveSection);
saveSection
.call(saveHeader)
.call(input)
.call(buttons);
}
function saveHeader(selection) {
var header = selection.selectAll('.notesSaveHeader')
.data([0]);
header.enter()
.append('h4')
.attr('class', '.notesSaveHeader')
.text(t('note.newComment'))
.merge(header);
}
function input(selection) {
var input = selection.selectAll('textarea')
.data([0]);
input.enter()
.append('textarea')
.attr('id', 'new-comment-input')
.attr('placeholder', t('note.inputPlaceholder'))
.attr('maxlength', 1000)
.call(utilNoAuto)
.on('input', change)
.on('blur', change)
.merge(input);
function change() {
_inputValue = this.value;
console.log(_inputValue);
dispatch.apply('modifiedInput');
}
}
function buttons(selection) {
// Buttons
var buttonSection = selection.selectAll('.buttons')
.data([0]);
// enter
var buttonEnter = buttonSection.enter()
.append('div')
.attr('class', 'buttons cf');
buttonEnter
.append('button')
.attr('class', 'secondary-action button cancel-button')
.append('span')
.attr('class', 'label')
.text(t('note.cancel'));
buttonEnter
.append('button')
.attr('class', 'action button save-button')
.append('span')
.attr('class', 'label')
.text(t('note.save'));
var status;
if (_note.status) {
status = _note.status === 'open' ? t('note.close') : t('note.reopen');
}
buttonEnter
.append('button')
.attr('class', _note.status + '-button status-button action button')
.append('span')
.attr('class', 'label')
.text(status);
// update
buttonSection = buttonSection
.merge(buttonEnter);
buttonSection.selectAll('.closed-button,.open-button')
.on('click', function() {
save(toggleNoteStatus);
dispatch.apply('toggleNote', this); // TODO: dispatch toggleNote event
});
buttonSection.selectAll('.cancel-button')
.on('click.cancel', cancel);
buttonSection.selectAll('.save-button')
.attr('disabled', function() {
var n = d3_select('#new-comment-input').node();
return (n && n.value.length) ? null : true;
})
.on('modifiedInput', function() {
// TODO: determine how to toggle button on input via triggering 'modifiedInput' event
})
.on('click.save', function() {
this.blur(); // avoid keeping focus on the button - #4641
save(addNoteComment);
dispatch.apply('saveNote', this, _newComment); // TODO: dispatch saveNote event
});
}
function render(selection) {
var header = selection.selectAll('.header')
.data([0]);
@@ -249,7 +50,153 @@ export function uiNoteEditor(context) {
.attr('class', 'modal-section note-editor')
.call(noteHeader.note(_note))
.call(noteComments.note(_note))
.call(newComment);
.call(noteSave);
}
function noteSave(selection) {
var isSelected = (_note && _note.id === context.selectedNoteID());
var noteSave = selection.selectAll('.note-save-section')
.data((isSelected ? [_note] : []), function(d) { return d.id; });
// exit
noteSave.exit()
.remove();
// enter
var noteSaveEnter = noteSave.enter()
.append('div')
.attr('class', 'note-save-section save-section cf');
noteSaveEnter
.append('h4')
.attr('class', '.note-save-header')
.text(t('note.newComment'));
noteSaveEnter
.append('textarea')
.attr('id', 'new-comment-input')
.attr('placeholder', t('note.inputPlaceholder'))
.attr('maxlength', 1000)
.call(utilNoAuto)
.on('input', change)
.on('blur', change);
// update
noteSave = noteSaveEnter
.merge(noteSave);
change();
function change() {
noteSave
.call(noteSaveButtons);
}
}
function noteSaveButtons(selection) {
var isSelected = (_note && _note.id === context.selectedNoteID());
var buttonSection = selection.selectAll('.buttons')
.data((isSelected ? [_note] : []), function(d) { return d.id; });
// exit
buttonSection.exit()
.remove();
// enter
var buttonEnter = buttonSection.enter()
.append('div')
.attr('class', 'buttons');
buttonEnter
.append('button')
.attr('class', 'button status-button action')
.append('span')
.attr('class', 'label');
buttonEnter
.append('button')
.attr('class', 'button comment-button action')
.append('span')
.attr('class', 'label')
.text(t('note.comment'));
// update
buttonSection = buttonSection
.merge(buttonEnter);
buttonSection.selectAll('.status-button')
.text(function(d) {
var n = d3_select('#new-comment-input').node();
var setStatus = (d.status === 'open' ? 'close' : 'open');
var andComment = ((n && n.value.length) ? '_comment' : '');
return t('note.' + setStatus + andComment);
})
.on('click.status', function() {
this.blur(); // avoid keeping focus on the button - #4641
// todo: the thing
});
buttonSection.selectAll('.comment-button')
.attr('disabled', function() {
var n = d3_select('#new-comment-input').node();
return (n && n.value.length) ? null : true;
})
.on('click.save', function() {
this.blur(); // avoid keeping focus on the button - #4641
// todo: the thing
});
}
function save() {
// var osm = context.connection();
// if (!osm) {
// context.enter(modeBrowse(context));
// return;
// }
// // If user somehow got logged out mid-save, try to reauthenticate..
// // This can happen if they were logged in from before, but the tokens are no longer valid.
// if (!osm.authenticated()) {
// // TODO: dispatch 'notAuthenticated' to give warning
// osm.authenticate(function(err) {
// if (err) { // quit save mode..
// context.enter(modeBrowse(context));
// return;
// } else {
// save(updateFunction); // continue where we left off..
// }
// });
// return;
// }
// function parseResults(results) { // TODO: simplify result parsing
// dispatch.call('change', results);
// // call success
// if (results) {
// success(results);
// }
// // otherwise, call failure
// else {
// failure(results);
// }
// }
// function success(results) {
// console.log('success!', results); // TODO: handle success
// dispatch.apply('updateNote');
// }
// function failure(results) { // TODO: handle failure & errors
// console.log('failure!', results);
// }
// updateFunction(parseResults);
}