diff --git a/app.js b/app.js
index 8681413..f981420 100644
--- a/app.js
+++ b/app.js
@@ -19,8 +19,9 @@ let editingEntryId = null; // null = no existing instrument entry
let editingOriginalRefIds = []; // ref IDs present when edit modal opened
// notes modal state
-let notesTuneId = null;
-let notesEntryId = null;
+let notesTuneId = null;
+let notesEntryId = null;
+let noteEditorState = null; // { type: 'tune'|'inst', noteId: null|number }
let unlocked = false;
@@ -840,35 +841,62 @@ function renderInstNotes(notes) {
});
}
-$('btn-add-tune-note').addEventListener('click', async () => {
- const text = prompt('Note:');
- if (!text) return;
- try {
- await apiFetch(`/tunes/${notesTuneId}/notes`, { method: 'POST', body: JSON.stringify({ note: text }) });
- await reloadNotesModal();
- } catch (e) { setStatus(e.message, true); }
-});
+$('btn-add-tune-note').addEventListener('click', () => showNoteEditor('tune', null));
+$('btn-add-inst-note').addEventListener('click', () => showNoteEditor('inst', null));
-$('btn-add-inst-note').addEventListener('click', async () => {
- const text = prompt('Note:');
- if (!text) return;
- try {
- await apiFetch(`/tunes/${notesTuneId}/instruments/${notesEntryId}/notes`,
- { method: 'POST', body: JSON.stringify({ note: text }) });
- await reloadNotesModal();
- } catch (e) { setStatus(e.message, true); }
-});
+function editTuneNote(n) { showNoteEditor('tune', n.id, n.note); }
+function editInstNote(n) { showNoteEditor('inst', n.id, n.note); }
-async function editTuneNote(n) {
- const text = prompt('Edit note:', n.note);
- if (text === null) return;
- try {
- await apiFetch(`/tunes/${notesTuneId}/notes/${n.id}`,
- { method: 'PATCH', body: JSON.stringify({ note: text }) });
- await reloadNotesModal();
- } catch (e) { setStatus(e.message, true); }
+function showNoteEditor(type, noteId, existingText = '') {
+ noteEditorState = { type, noteId };
+ $('note-editor-title').textContent = noteId ? 'Edit note' : 'Add note';
+ $('note-editor-ta').value = existingText;
+ $('note-editor-modal').showModal();
+ $('note-editor-ta').focus();
}
+function hideNoteEditor() {
+ noteEditorState = null;
+ $('note-editor-ta').value = '';
+ $('note-editor-modal').close();
+}
+
+$('btn-note-cancel').addEventListener('click', hideNoteEditor);
+
+$('note-editor-ta').addEventListener('keydown', e => {
+ if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') $('btn-note-save').click();
+ if (e.key === 'Escape') hideNoteEditor();
+});
+
+$('btn-note-save').addEventListener('click', async () => {
+ if (!noteEditorState) return;
+ const text = $('note-editor-ta').value.trim();
+ if (!text) return;
+ const { type, noteId } = noteEditorState;
+ $('btn-note-save').disabled = true;
+ try {
+ if (type === 'tune') {
+ await apiFetch(
+ noteId ? `/tunes/${notesTuneId}/notes/${noteId}` : `/tunes/${notesTuneId}/notes`,
+ { method: noteId ? 'PATCH' : 'POST', body: JSON.stringify({ note: text }) }
+ );
+ } else {
+ await apiFetch(
+ noteId
+ ? `/tunes/${notesTuneId}/instruments/${notesEntryId}/notes/${noteId}`
+ : `/tunes/${notesTuneId}/instruments/${notesEntryId}/notes`,
+ { method: noteId ? 'PATCH' : 'POST', body: JSON.stringify({ note: text }) }
+ );
+ }
+ hideNoteEditor();
+ await reloadNotesModal();
+ } catch (e) {
+ setStatus(e.message, true);
+ } finally {
+ $('btn-note-save').disabled = false;
+ }
+});
+
async function deleteTuneNote(noteId) {
if (!confirm('Delete this note?')) return;
try {
@@ -877,16 +905,6 @@ async function deleteTuneNote(noteId) {
} catch (e) { setStatus(e.message, true); }
}
-async function editInstNote(n) {
- const text = prompt('Edit note:', n.note);
- if (text === null) return;
- try {
- await apiFetch(`/tunes/${notesTuneId}/instruments/${notesEntryId}/notes/${n.id}`,
- { method: 'PATCH', body: JSON.stringify({ note: text }) });
- await reloadNotesModal();
- } catch (e) { setStatus(e.message, true); }
-}
-
async function deleteInstNote(noteId) {
if (!confirm('Delete this note?')) return;
try {
diff --git a/index.html b/index.html
index b0eb916..b2aab72 100644
--- a/index.html
+++ b/index.html
@@ -171,7 +171,7 @@
-
+
+
+
+