164 lines
9.2 KiB
Python
164 lines
9.2 KiB
Python
import os
|
|
|
|
index_path = r'z:\source\forgejo\spotnotes.app\static\assets\js\index.js'
|
|
with open(index_path, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
# Add the filter input to the header
|
|
header_replace = """
|
|
<div style="display:flex; align-items:center;">
|
|
<button id="btn-back-pads" style="background:none; border:none; font-size:1.5rem; cursor:pointer; margin-right:10px;">←</button>
|
|
<h2 style="font-size:1.2rem; margin:0;">${window.SpotNotes.escapeHtml(currentName)}</h2>
|
|
<button onclick="window.SpotNotes.shareNotepad(${padId}, '${token || ''}')" style="border:none; background:none; cursor:pointer; margin-left:10px;" title="Share">🔗</button>
|
|
${manageShareBtn}
|
|
${exportBtn}
|
|
</div>
|
|
<div style="margin-top: 10px;">
|
|
<input type="text" id="filter-active-notes" placeholder="Filter notes..." style="width: 100%; padding: 5px; margin-bottom: 5px; box-sizing: border-box; border: 1px solid #ccc; border-radius: 4px;">
|
|
</div>
|
|
${addNoteBtn}
|
|
"""
|
|
content = content.replace("""
|
|
<div style="display:flex; align-items:center;">
|
|
<button id="btn-back-pads" style="background:none; border:none; font-size:1.5rem; cursor:pointer; margin-right:10px;">←</button>
|
|
<h2 style="font-size:1.2rem; margin:0;">${window.SpotNotes.escapeHtml(currentName)}</h2>
|
|
<button onclick="window.SpotNotes.shareNotepad(${padId}, '${token || ''}')" style="border:none; background:none; cursor:pointer; margin-left:10px;" title="Share">🔗</button>
|
|
${manageShareBtn}
|
|
${exportBtn}
|
|
</div>
|
|
${addNoteBtn}
|
|
""", header_replace)
|
|
|
|
# Now, extract the rendering logic into a new function `window.SpotNotes.renderActiveNotesList`
|
|
old_render_block = """
|
|
// Render Sidebar List
|
|
sidebarBody.innerHTML = '';
|
|
if (notes.length === 0) {
|
|
sidebarBody.innerHTML = '<p style="padding:10px; color:#666;">No notes yet.</p>';
|
|
}
|
|
|
|
notes.forEach(note => {
|
|
const item = document.createElement('div');
|
|
item.className = 'sidebar-note-item';
|
|
|
|
let actionBtns = '';
|
|
if (window.SpotNotes.activePadCanWrite) {
|
|
const escapedTitle = window.SpotNotes.escapeHtml(note.title).replace(/'/g, "\\\\'").replace(/"/g, '"');
|
|
const escapedContent = window.SpotNotes.escapeHtml(note.content).replace(/'/g, "\\\\'").replace(/"/g, '"').replace(/\\n/g, '\\\\n');
|
|
actionBtns = `
|
|
<button onclick="event.stopPropagation(); openEditNoteModal(${note.id}, '${escapedTitle}', '${escapedContent}')" style="font-size:0.7rem; color:#007bff; border:none; background:none; cursor:pointer; text-decoration:underline;">Edit</button>
|
|
<button onclick="event.stopPropagation(); window.SpotNotes.deleteNote(${note.id})" style="font-size:0.7rem; color:#dc3545; border:none; background:none; cursor:pointer; text-decoration:underline;">Delete</button>
|
|
`;
|
|
} else if (window.SpotNotes.activePadIsPublic) {
|
|
actionBtns = `<button onclick="event.stopPropagation(); window.SpotNotes.reportNote(${note.id})" style="font-size:0.7rem; color:orange; border:none; background:none; cursor:pointer; text-decoration:underline;">Report</button>`;
|
|
}
|
|
|
|
const dateStr = new Date(note.created_at).toLocaleString();
|
|
|
|
item.innerHTML = `
|
|
<div style="font-weight:bold;">${window.SpotNotes.escapeHtml(note.title)}</div>
|
|
<div style="font-size:0.8rem; color:#666; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">${window.SpotNotes.escapeHtml(note.content)}</div>
|
|
<div style="font-size:0.7rem; color:#888; margin-top:2px;">
|
|
${dateStr} <br> ${note.lat.toFixed(5)}, ${note.lng.toFixed(5)}
|
|
</div>
|
|
<div style="text-align:right; margin-top:4px;">
|
|
<a href="https://www.google.com/maps/dir/?api=1&destination=${note.lat},${note.lng}" target="_blank" onclick="event.stopPropagation();" style="font-size:0.7rem; color:#28a745; text-decoration:underline; margin-right: 5px;">Directions</a>
|
|
${actionBtns}
|
|
</div>
|
|
`;
|
|
item.addEventListener('click', () => {
|
|
window.SpotNotes.stopTracking();
|
|
window.SpotNotes.map.setView([note.lat, note.lng], 16);
|
|
});
|
|
sidebarBody.appendChild(item);
|
|
});
|
|
|
|
window.SpotNotes.renderMapMarkers();
|
|
"""
|
|
|
|
new_render_call = """
|
|
// Render Sidebar List
|
|
window.SpotNotes.renderActiveNotesList();
|
|
"""
|
|
|
|
content = content.replace(old_render_block, new_render_call)
|
|
|
|
# Add event listener for the filter input inside loadNotesForPad
|
|
filter_listener = """
|
|
const filterInput = document.getElementById('filter-active-notes');
|
|
if (filterInput) {
|
|
filterInput.addEventListener('keyup', (e) => {
|
|
window.SpotNotes.renderActiveNotesList(e.target.value);
|
|
});
|
|
}
|
|
"""
|
|
content = content.replace(new_render_call, new_render_call + filter_listener)
|
|
|
|
|
|
# Now append the function window.SpotNotes.renderActiveNotesList to the end of the file
|
|
render_function = """
|
|
window.SpotNotes.renderActiveNotesList = function(filterText = '') {
|
|
const sidebarBody = document.getElementById('sidebar-body');
|
|
if (!sidebarBody) return;
|
|
|
|
sidebarBody.innerHTML = '';
|
|
|
|
const filterLower = filterText.toLowerCase();
|
|
const filteredNotes = window.SpotNotes.activeNotes.filter(note => {
|
|
return note.title.toLowerCase().includes(filterLower) || note.content.toLowerCase().includes(filterLower);
|
|
});
|
|
|
|
if (filteredNotes.length === 0) {
|
|
sidebarBody.innerHTML = '<p style="padding:10px; color:#666;">No notes match.</p>';
|
|
}
|
|
|
|
filteredNotes.forEach(note => {
|
|
const item = document.createElement('div');
|
|
item.className = 'sidebar-note-item';
|
|
|
|
let actionBtns = '';
|
|
if (window.SpotNotes.activePadCanWrite) {
|
|
const escapedTitle = window.SpotNotes.escapeHtml(note.title).replace(/'/g, "\\\\'").replace(/"/g, '"');
|
|
const escapedContent = window.SpotNotes.escapeHtml(note.content).replace(/'/g, "\\\\'").replace(/"/g, '"').replace(/\\n/g, '\\\\n');
|
|
actionBtns = `
|
|
<button onclick="event.stopPropagation(); openEditNoteModal(${note.id}, '${escapedTitle}', '${escapedContent}')" style="font-size:0.7rem; color:#007bff; border:none; background:none; cursor:pointer; text-decoration:underline;">Edit</button>
|
|
<button onclick="event.stopPropagation(); window.SpotNotes.deleteNote(${note.id})" style="font-size:0.7rem; color:#dc3545; border:none; background:none; cursor:pointer; text-decoration:underline;">Delete</button>
|
|
`;
|
|
} else if (window.SpotNotes.activePadIsPublic) {
|
|
actionBtns = `<button onclick="event.stopPropagation(); window.SpotNotes.reportNote(${note.id})" style="font-size:0.7rem; color:orange; border:none; background:none; cursor:pointer; text-decoration:underline;">Report</button>`;
|
|
}
|
|
|
|
const dateStr = new Date(note.created_at).toLocaleString();
|
|
|
|
item.innerHTML = `
|
|
<div style="font-weight:bold;">${window.SpotNotes.escapeHtml(note.title)}</div>
|
|
<div style="font-size:0.8rem; color:#666; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">${window.SpotNotes.escapeHtml(note.content)}</div>
|
|
<div style="font-size:0.7rem; color:#888; margin-top:2px;">
|
|
${dateStr} <br> ${note.lat.toFixed(5)}, ${note.lng.toFixed(5)}
|
|
</div>
|
|
<div style="text-align:right; margin-top:4px;">
|
|
<a href="https://www.google.com/maps/dir/?api=1&destination=${note.lat},${note.lng}" target="_blank" onclick="event.stopPropagation();" style="font-size:0.7rem; color:#28a745; text-decoration:underline; margin-right: 5px;">Directions</a>
|
|
${actionBtns}
|
|
</div>
|
|
`;
|
|
item.addEventListener('click', () => {
|
|
window.SpotNotes.stopTracking();
|
|
window.SpotNotes.map.setView([note.lat, note.lng], 16);
|
|
});
|
|
sidebarBody.appendChild(item);
|
|
});
|
|
|
|
// We do NOT call window.SpotNotes.renderMapMarkers() here, because we only want to filter the sidebar, not the map itself.
|
|
// Wait, the task says: "filtering the existing activeNotes array before re-rendering the sidebar list".
|
|
// It doesn't strictly say to filter the map markers, but maybe we should?
|
|
// Usually a sidebar filter only filters the list if it says "Add a simple, fast text input filter floating above the note list in the sidebar... filtering the existing activeNotes array before re-rendering the sidebar list".
|
|
// We will leave the map markers as they are to show all active notes. Or wait, if we only render the list, the map shows everything. Let's just leave the map markers as is (calling renderMapMarkers once on load).
|
|
};
|
|
"""
|
|
|
|
content += "\n" + render_function
|
|
|
|
with open(index_path, 'w', encoding='utf-8') as f:
|
|
f.write(content)
|
|
|
|
print('Filtered active notes logic applied')
|