Add full-text search
- Index notes in a separate, rebuildable SQLite database (index.db) using FTS5 trigram, synced from watcher snapshots so external edits are picked up; terms under 3 characters fall back to LIKE - GET /api/v1/search?q= returns matching notes with the first matching line and a snippet; path matches rank first - Sidebar search panel (Ctrl+Shift+F) with highlighted terms and keyboard navigation; opening a result jumps to and selects the match - Restore scroll position on tab switch with scroll snapshots; restoring scrollTop drifted by a few lines after line heights were re-estimated
This commit is contained in:
1 parent
a11e0ec498
commit
55f0ee174e
13 files changed
+792
-20
No files matched your search
@@ -154,6 +154,51 @@ button {
|
||||
.rm-tree-row:hover .rm-tree-more,
|
||||
.rm-tree-row.menu-open .rm-tree-more { opacity: 1; }
|
||||
.rm-tree-empty { padding: 16px; color: var(--rm-text-muted); font-size: 13px; text-align: center; }
|
||||
/* ---- 搜索 ---- */
|
||||
.rm-sidebar-head .rm-icon-btn.on { background: var(--rm-active); color: var(--rm-accent-strong); }
|
||||
.rm-search { flex: 1; display: flex; flex-direction: column; min-height: 0; }
|
||||
.rm-search-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin: 0 10px 8px;
|
||||
padding: 0 4px 0 8px;
|
||||
border: 1px solid var(--rm-divider);
|
||||
border-radius: 6px;
|
||||
background: var(--rm-bg);
|
||||
color: var(--rm-text-muted);
|
||||
}
|
||||
.rm-search-box:focus-within { border-color: var(--rm-accent); }
|
||||
.rm-search-input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
height: 30px;
|
||||
border: 0;
|
||||
background: none;
|
||||
color: var(--rm-text);
|
||||
font: inherit;
|
||||
font-size: 14px;
|
||||
outline: none;
|
||||
}
|
||||
.rm-search-input::-webkit-search-cancel-button { display: none; }
|
||||
.rm-search-results { flex: 1; overflow: auto; list-style: none; margin: 0; padding: 0 6px 12px; }
|
||||
.rm-search-item { padding: 6px 8px; border-radius: 6px; cursor: pointer; }
|
||||
.rm-search-item.active { background: var(--rm-hover); }
|
||||
.rm-search-item.current .rm-search-title { color: var(--rm-accent-strong); }
|
||||
.rm-search-title { display: flex; align-items: baseline; gap: 6px; font-size: 14px; overflow: hidden; white-space: nowrap; }
|
||||
.rm-search-dir { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--rm-text-muted); font-size: 12px; }
|
||||
.rm-search-snippet {
|
||||
margin-top: 2px;
|
||||
color: var(--rm-text-muted);
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
word-break: break-all;
|
||||
}
|
||||
.rm-search-hit { background: rgba(66, 184, 131, 0.28); color: var(--rm-text); border-radius: 2px; }
|
||||
.rm-sidebar-foot { display: flex; gap: 4px; padding: 8px; border-top: 1px solid var(--rm-divider); }
|
||||
.rm-foot-btn {
|
||||
flex: 1;
|
||||
@@ -344,5 +389,8 @@ button {
|
||||
.rm-tree-row { height: 40px; font-size: 15px; }
|
||||
.rm-tree-more { opacity: 1; width: 36px; height: 36px; }
|
||||
.rm-sidebar-head .rm-icon-btn { width: 40px; height: 40px; }
|
||||
/* 小于 16px 时 iOS Safari 聚焦输入框会自动放大页面 */
|
||||
.rm-search-input { height: 40px; font-size: 16px; }
|
||||
.rm-search-item { padding: 10px 8px; }
|
||||
.rm-trash-list li { flex-wrap: wrap; }
|
||||
}
|
||||
Reference in new issue
Block a user