mirror of
https://github.com/NotAShelf/stash.git
synced 2026-04-17 08:09:52 +00:00
commands/list: full TUI rewrite for better perf
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I49009a89542fdeeea31d3755108b53d06a6a6964
This commit is contained in:
parent
0215ebeb6c
commit
88c1f0f158
2 changed files with 416 additions and 163 deletions
|
|
@ -734,6 +734,76 @@ impl ClipboardDb for SqliteClipboardDb {
|
|||
}
|
||||
|
||||
impl SqliteClipboardDb {
|
||||
/// Count visible clipboard entries (respects include_expired filter).
|
||||
pub fn count_entries(
|
||||
&self,
|
||||
include_expired: bool,
|
||||
) -> Result<usize, StashError> {
|
||||
let count: i64 = if include_expired {
|
||||
self
|
||||
.conn
|
||||
.query_row("SELECT COUNT(*) FROM clipboard", [], |r| r.get(0))
|
||||
} else {
|
||||
self.conn.query_row(
|
||||
"SELECT COUNT(*) FROM clipboard WHERE (is_expired IS NULL OR \
|
||||
is_expired = 0)",
|
||||
[],
|
||||
|r| r.get(0),
|
||||
)
|
||||
}
|
||||
.map_err(|e| StashError::ListDecode(e.to_string().into()))?;
|
||||
Ok(count.max(0) as usize)
|
||||
}
|
||||
|
||||
/// Fetch a window of entries for TUI virtual scrolling.
|
||||
///
|
||||
/// Returns `(id, preview_string, mime_string)` tuples for at most
|
||||
/// `limit` rows starting at `offset` (0-indexed) in the canonical
|
||||
/// display order (most-recently-accessed first, then id DESC).
|
||||
pub fn fetch_entries_window(
|
||||
&self,
|
||||
include_expired: bool,
|
||||
offset: usize,
|
||||
limit: usize,
|
||||
preview_width: u32,
|
||||
) -> Result<Vec<(i64, String, String)>, StashError> {
|
||||
let query = if include_expired {
|
||||
"SELECT id, contents, mime FROM clipboard ORDER BY \
|
||||
COALESCE(last_accessed, 0) DESC, id DESC LIMIT ?1 OFFSET ?2"
|
||||
} else {
|
||||
"SELECT id, contents, mime FROM clipboard WHERE (is_expired IS NULL OR \
|
||||
is_expired = 0) ORDER BY COALESCE(last_accessed, 0) DESC, id DESC LIMIT \
|
||||
?1 OFFSET ?2"
|
||||
};
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.prepare(query)
|
||||
.map_err(|e| StashError::ListDecode(e.to_string().into()))?;
|
||||
let mut rows = stmt
|
||||
.query(rusqlite::params![limit as i64, offset as i64])
|
||||
.map_err(|e| StashError::ListDecode(e.to_string().into()))?;
|
||||
|
||||
let mut window = Vec::with_capacity(limit);
|
||||
while let Some(row) = rows
|
||||
.next()
|
||||
.map_err(|e| StashError::ListDecode(e.to_string().into()))?
|
||||
{
|
||||
let id: i64 = row
|
||||
.get(0)
|
||||
.map_err(|e| StashError::ListDecode(e.to_string().into()))?;
|
||||
let contents: Vec<u8> = row
|
||||
.get(1)
|
||||
.map_err(|e| StashError::ListDecode(e.to_string().into()))?;
|
||||
let mime: Option<String> = row
|
||||
.get(2)
|
||||
.map_err(|e| StashError::ListDecode(e.to_string().into()))?;
|
||||
let preview = preview_entry(&contents, mime.as_deref(), preview_width);
|
||||
let mime_str = mime.unwrap_or_default();
|
||||
window.push((id, preview, mime_str));
|
||||
}
|
||||
Ok(window)
|
||||
}
|
||||
|
||||
/// Get current Unix timestamp with sub-second precision
|
||||
pub fn now() -> f64 {
|
||||
std::time::SystemTime::now()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue