diff --git a/extension/src/popup/components/item-list.ts b/extension/src/popup/components/item-list.ts
index 111b1ef..9b03960 100644
--- a/extension/src/popup/components/item-list.ts
+++ b/extension/src/popup/components/item-list.ts
@@ -25,11 +25,10 @@ function typeIcon(t: ItemType): string {
}
}
-export function renderItemList(app: HTMLElement): void {
+function buildRowsHtml(): string {
const state = getState();
const filtered = getFilteredEntries();
-
- const rowsHtml = filtered.length > 0
+ return filtered.length > 0
? filtered.map(([id, e], i) => `
${typeIcon(e.type)} ${escapeHtml(e.title)}${e.attachment_summaries.length > 0 ? ' 📎' : ''}
@@ -37,7 +36,28 @@ export function renderItemList(app: HTMLElement): void {
`).join('')
: 'no items
';
+}
+function updateItemList(): void {
+ const list = document.getElementById('item-list');
+ if (list) {
+ list.innerHTML = buildRowsHtml();
+ wireRowClicks();
+ }
+}
+
+function wireRowClicks(): void {
+ document.querySelectorAll('.entry-row').forEach(row => {
+ row.addEventListener('click', async () => {
+ const id = (row as HTMLElement).dataset.id!;
+ document.removeEventListener('keydown', handleListKeydown);
+ await openItem(id);
+ });
+ });
+}
+
+export function renderItemList(app: HTMLElement): void {
+ const state = getState();
app.innerHTML = `
@@ -50,7 +70,7 @@ export function renderItemList(app: HTMLElement): void {
- ${rowsHtml}
+ ${buildRowsHtml()}
/ search
@@ -64,7 +84,12 @@ export function renderItemList(app: HTMLElement): void {
const searchInput = document.getElementById('search-input') as HTMLInputElement | null;
searchInput?.addEventListener('input', () => {
- setState({ searchQuery: searchInput.value, selectedIndex: 0 });
+ const state2 = getState();
+ state2.searchQuery = searchInput.value;
+ state2.selectedIndex = 0;
+ const list = document.getElementById('item-list');
+ if (list) list.innerHTML = buildRowsHtml();
+ wireRowClicks();
});
document.getElementById('new-btn')?.addEventListener('click', () => {
@@ -98,21 +123,9 @@ export function renderItemList(app: HTMLElement): void {
showSettingsPicker(e.currentTarget as HTMLElement);
});
- // Item row clicks.
- const rows = app.querySelectorAll('.entry-row');
- rows.forEach(row => {
- row.addEventListener('click', async () => {
- const id = (row as HTMLElement).dataset.id!;
- document.removeEventListener('keydown', handleListKeydown);
- await openItem(id);
- });
- });
+ wireRowClicks();
- // Keyboard navigation.
document.addEventListener('keydown', handleListKeydown);
-
- // Focus search on open.
- searchInput?.focus();
}
async function openItem(id: ItemId): Promise {
@@ -195,17 +208,19 @@ function handleListKeydown(e: KeyboardEvent): void {
if (e.key === 'ArrowDown') {
e.preventDefault();
const max = Math.max(filtered.length - 1, 0);
- setState({ selectedIndex: Math.min(state.selectedIndex + 1, max) });
+ state.selectedIndex = Math.min(state.selectedIndex + 1, max);
+ updateItemList();
return;
}
if (e.key === 'ArrowUp') {
e.preventDefault();
- setState({ selectedIndex: Math.max(state.selectedIndex - 1, 0) });
+ state.selectedIndex = Math.max(state.selectedIndex - 1, 0);
+ updateItemList();
return;
}
- if (e.key === 'Enter' && !isSearch) {
+ if (e.key === 'Enter') {
e.preventDefault();
const selected = filtered[state.selectedIndex];
if (selected) {