spotnotes.app/static/assets/js/actions.js

188 lines
7.5 KiB
JavaScript
Raw Normal View History

2026-05-12 23:58:18 +00:00
document.addEventListener('DOMContentLoaded', () => {
initModals();
});
let activeNotepadId = null; // Tracks which notepad is currently selected
function initModals() {
// --- Create Notepad Logic ---
const modalPad = document.getElementById('modal-create-pad');
const btnOpenPad = document.getElementById('btn-create-pad');
const formPad = document.getElementById('form-create-pad');
if (btnOpenPad) {
2026-05-12 23:58:18 +00:00
btnOpenPad.addEventListener('click', () => {
modalPad.classList.remove('hidden');
});
}
if (formPad) {
2026-05-12 23:58:18 +00:00
formPad.addEventListener('submit', async (e) => {
e.preventDefault();
const name = document.getElementById('pad-name').value.trim();
2026-05-12 23:58:18 +00:00
const isPublic = document.getElementById('pad-public').checked;
const color = document.getElementById('pad-color').value;
2026-05-12 23:58:18 +00:00
try {
let encryptedKey = null;
let padKeyObj = null;
// For private notepads, generate an AES-GCM 256 key and wrap with user's RSA public key
if (!isPublic) {
if (!window.SpotNotes.currentUser || !window.SpotNotes.currentUser.public_key) {
alert('Your user account does not have an encryption key configured. Please log out and register or log in again.');
return;
}
const keyData = await window.SpotCrypto.createNotepadKey(window.SpotNotes.currentUser.public_key);
encryptedKey = keyData.encryptedKeyB64;
padKeyObj = keyData.padKey;
}
2026-05-12 23:58:18 +00:00
const res = await fetch('/api/notepads', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name,
is_public: isPublic,
color: color,
encrypted_key: encryptedKey
})
2026-05-12 23:58:18 +00:00
});
if (res.ok) {
const newPad = await res.json();
modalPad.classList.add('hidden');
formPad.reset();
if (!isPublic && padKeyObj) {
window.SpotCrypto.setCachedPadKey(newPad.id, padKeyObj);
}
2026-05-12 23:58:18 +00:00
// Transition to the new notepad
if (typeof window.SpotNotes.loadNotesForPad === 'function') {
window.SpotNotes.loadNotesForPad(newPad.id, newPad.name, newPad.is_public, newPad.owner_id, false, null, true, encryptedKey);
}
2026-05-12 23:58:18 +00:00
} else {
const err = await res.json();
alert(err.error || 'Failed to create notepad');
2026-05-12 23:58:18 +00:00
}
} catch (err) {
console.error(err);
alert('An error occurred during notepad creation.');
2026-05-12 23:58:18 +00:00
}
});
}
// --- Create Note Logic ---
const modalNote = document.getElementById('modal-create-note');
const formNote = document.getElementById('form-create-note');
if (formNote) {
2026-05-12 23:58:18 +00:00
formNote.addEventListener('submit', async (e) => {
e.preventDefault();
const targetPadId = activeNotepadId || window.SpotNotes.activePadId;
if (!targetPadId) {
2026-05-12 23:58:18 +00:00
alert("No notepad selected!");
return;
}
const title = document.getElementById('note-title').value.trim();
2026-05-12 23:58:18 +00:00
const content = document.getElementById('note-content').value;
// Use current map center
const center = window.SpotNotes.map ? window.SpotNotes.map.getCenter() : { lat: 0, lng: 0 };
const isPrivate = !window.SpotNotes.activePadIsPublic;
2026-05-12 23:58:18 +00:00
try {
let notePayload = {};
if (isPrivate) {
// Private note: client-side zero-knowledge encryption
let padKey = window.SpotCrypto.getCachedPadKey(targetPadId);
if (!padKey && window.SpotNotes.activePadEncryptedKey) {
padKey = await window.SpotCrypto.unwrapNotepadKey(targetPadId, window.SpotNotes.activePadEncryptedKey);
}
if (!padKey) {
alert("Encryption key for this private notepad is not available. Please unlock your account or re-enter via share link.");
return;
}
const encPayload = await window.SpotCrypto.encryptNote({
2026-05-12 23:58:18 +00:00
title,
content,
lat: center.lat,
lng: center.lng
}, padKey);
notePayload = {
notepad_id: targetPadId,
content: encPayload // Ciphertext stored at rest on server
};
} else {
// Public note: unencrypted at rest
notePayload = {
notepad_id: targetPadId,
title,
content,
lat: center.lat,
lng: center.lng
};
}
const res = await fetch('/api/notes', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(notePayload)
2026-05-12 23:58:18 +00:00
});
if (res.ok) {
modalNote.classList.add('hidden');
formNote.reset();
// Refresh notes
if (typeof window.SpotNotes.loadNotesForPad === 'function') {
window.SpotNotes.loadNotesForPad(targetPadId);
}
2026-05-12 23:58:18 +00:00
} else {
const err = await res.json();
alert(err.error || 'Failed to create note');
2026-05-12 23:58:18 +00:00
}
} catch (err) {
console.error(err);
alert('An error occurred during note creation.');
2026-05-12 23:58:18 +00:00
}
});
}
// Close buttons
document.querySelectorAll('.close-modal').forEach(btn => {
btn.addEventListener('click', (e) => {
e.target.closest('.modal').classList.add('hidden');
});
});
}
// Helper to open edit notepad modal (called from index.js)
window.openEditPadModal = function(id, currentName, currentPublic, currentColor = '#3388ff') {
2026-05-12 23:58:18 +00:00
document.getElementById('pad-id-edit').value = id;
document.getElementById('pad-name-edit').value = currentName;
document.getElementById('pad-public-edit').checked = currentPublic;
document.getElementById('pad-color-edit').value = currentColor;
2026-05-12 23:58:18 +00:00
document.getElementById('modal-edit-pad').classList.remove('hidden');
};
// Helper to open edit note modal (called from index.js)
window.openEditNoteModal = function(id, currentTitle, currentContent) {
document.getElementById('note-id-edit').value = id;
document.getElementById('note-title-edit').value = currentTitle;
document.getElementById('note-content-edit').value = currentContent;
document.getElementById('modal-edit-note').classList.remove('hidden');
};
// Helper to open note modal (called from index.js)
2026-06-02 04:22:59 +00:00
window.openCreateNoteModal = function(notepadId) {
2026-05-12 23:58:18 +00:00
activeNotepadId = notepadId;
document.getElementById('modal-create-note').classList.remove('hidden');
2026-06-02 04:22:59 +00:00
};