spotnotes.app/static/assets/js/search.js

98 lines
4 KiB
JavaScript
Raw Normal View History

2026-05-12 23:58:18 +00:00
document.addEventListener('DOMContentLoaded', () => {
const searchInput = document.getElementById('search-input');
const searchForm = document.getElementById('search-form');
if (searchInput && searchForm) {
const performSearch = async (e) => {
if (e) e.preventDefault();
const query = searchInput.value.trim();
if (!query) return;
const qLower = query.toLowerCase();
let publicNotes = [];
let privateNotes = [];
// 1. Search Public Notes (Backend)
2026-05-12 23:58:18 +00:00
try {
const res = await fetch(`/api/search?q=${encodeURIComponent(query)}`);
if (res.ok) {
publicNotes = await res.json();
2026-05-12 23:58:18 +00:00
} else {
console.error("Search API failed:", res.status);
}
} catch (e) {
console.error("Search error:", e);
}
// 2. Search Private Notes (Client-Side Decryption for Zero-Knowledge Privacy)
if (window.SpotNotes && window.SpotNotes.isLoggedIn) {
try {
const mineRes = await fetch('/api/notes/mine');
if (mineRes.ok) {
const myRawNotes = await mineRes.json();
for (const note of myRawNotes) {
let decryptedNote = note;
if (note.is_encrypted && window.SpotCrypto) {
let padKey = window.SpotCrypto.getCachedPadKey(note.notepad_id);
if (!padKey && note.notepad && note.notepad.encrypted_key) {
padKey = await window.SpotCrypto.unwrapNotepadKey(note.notepad_id, note.notepad.encrypted_key);
}
decryptedNote = await window.SpotCrypto.decryptNote(note, padKey);
}
const titleMatch = (decryptedNote.title || '').toLowerCase().includes(qLower);
const contentMatch = (decryptedNote.content || '').toLowerCase().includes(qLower);
if (titleMatch || contentMatch) {
privateNotes.push(decryptedNote);
}
}
}
} catch (e) {
console.warn("Error searching private notes locally:", e);
}
}
// Combine unique notes
const seenIds = new Set();
const combinedNotes = [];
[...privateNotes, ...publicNotes].forEach(note => {
if (!seenIds.has(note.id)) {
seenIds.add(note.id);
combinedNotes.push(note);
}
});
// If notes found, display them
if (combinedNotes.length > 0) {
if (window.SpotNotes && window.SpotNotes.displaySearchResults) {
window.SpotNotes.displaySearchResults(combinedNotes, null, query);
2026-05-12 23:58:18 +00:00
}
return;
}
// 3. Fallback: Search Location (Nominatim) if no notes found
2026-05-12 23:58:18 +00:00
let location = null;
try {
const nomRes = await fetch(`/api/geocode?q=${encodeURIComponent(query)}`);
const nomData = await nomRes.json();
if (nomData && nomData.length > 0) {
location = {
lat: parseFloat(nomData[0].lat),
lng: parseFloat(nomData[0].lon)
};
}
} catch (e) {
console.error("Geocoding error:", e);
}
// 4. Update UI
if (window.SpotNotes && window.SpotNotes.displaySearchResults) {
window.SpotNotes.displaySearchResults(combinedNotes, location, query);
2026-05-12 23:58:18 +00:00
}
};
searchForm.addEventListener('submit', performSearch);
}
});