diff options
author | Ellie Huxtable <ellie@elliehuxtable.com> | 2024-05-03 14:03:07 +0100 |
---|---|---|
committer | Ellie Huxtable <ellie@elliehuxtable.com> | 2024-05-03 14:51:29 +0100 |
commit | 3e5e8154237defbe6234dfb172c548cca06e4f4e (patch) | |
tree | 314adf1782816c5037abee149bb5e8bff01ab4c1 | |
parent | a5d44601afad0ee6fc48b4eb81d92ae200646f6e (diff) |
scroll search results now tooellie/ui-history-explore
-rw-r--r-- | crates/atuin-common/src/shell.rs | 2 | ||||
-rw-r--r-- | ui/backend/src/db.rs | 20 | ||||
-rw-r--r-- | ui/backend/src/main.rs | 10 | ||||
-rw-r--r-- | ui/src/components/HistorySearch.tsx | 12 | ||||
-rw-r--r-- | ui/src/pages/History.tsx | 13 | ||||
-rw-r--r-- | ui/src/state/store.ts | 12 |
6 files changed, 38 insertions, 31 deletions
diff --git a/crates/atuin-common/src/shell.rs b/crates/atuin-common/src/shell.rs index 9726ce4d..afdccea7 100644 --- a/crates/atuin-common/src/shell.rs +++ b/crates/atuin-common/src/shell.rs @@ -116,7 +116,7 @@ impl Shell { let shell = self.to_string(); let output = Command::new(shell) - .arg("-c") + .arg("-ic") .args(args) .output() .map_err(|e| ShellError::ExecError(e.to_string()))?; diff --git a/ui/backend/src/db.rs b/ui/backend/src/db.rs index 2b9dd095..7e29302a 100644 --- a/ui/backend/src/db.rs +++ b/ui/backend/src/db.rs @@ -98,16 +98,17 @@ impl HistoryDB { Ok(Self(sqlite)) } - pub async fn list(&self, end: u64, limit: Option<usize>) -> Result<Vec<History>, String> { + pub async fn list( + &self, + offset: Option<u64>, + limit: Option<usize>, + ) -> Result<Vec<History>, String> { let query = if let Some(limit) = limit { - sqlx::query( - "select * from history where timestamp < ?1 order by timestamp desc limit ?2", - ) - .bind(end as i64) - .bind(limit as i64) + sqlx::query("select * from history order by timestamp desc limit ?1 offset ?2") + .bind(limit as i64) + .bind(offset.unwrap_or(0) as i64) } else { - sqlx::query("select * from history where timestamp < ?1 order by timestamp desc") - .bind(end as i64) + sqlx::query("select * from history order by timestamp desc") }; let history: Vec<History> = query @@ -137,7 +138,7 @@ impl HistoryDB { Ok(history) } - pub async fn search(&self, query: &str) -> Result<Vec<UIHistory>, String> { + pub async fn search(&self, offset: Option<u64>, query: &str) -> Result<Vec<UIHistory>, String> { let context = Context { session: "".to_string(), cwd: "".to_string(), @@ -148,6 +149,7 @@ impl HistoryDB { let filters = OptFilters { limit: Some(200), + offset: offset.map(|offset| offset as i64), ..OptFilters::default() }; diff --git a/ui/backend/src/main.rs b/ui/backend/src/main.rs index 6a92df1c..ce248d61 100644 --- a/ui/backend/src/main.rs +++ b/ui/backend/src/main.rs @@ -26,14 +26,14 @@ struct HomeInfo { } #[tauri::command] -async fn list(minTimestamp: Option<u64>) -> Result<Vec<UIHistory>, String> { +async fn list(offset: Option<u64>) -> Result<Vec<UIHistory>, String> { let settings = Settings::new().map_err(|e| e.to_string())?; let db_path = PathBuf::from(settings.db_path.as_str()); let db = HistoryDB::new(db_path, settings.local_timeout).await?; let history = db - .list(minTimestamp.unwrap_or(time::OffsetDateTime::now_utc().unix_timestamp_nanos() as u64), Some(100)) + .list(Some(offset.unwrap_or(0)), Some(100)) .await? .into_iter() .map(|h| h.into()) @@ -43,13 +43,13 @@ async fn list(minTimestamp: Option<u64>) -> Result<Vec<UIHistory>, String> { } #[tauri::command] -async fn search(query: String) -> Result<Vec<UIHistory>, String> { +async fn search(query: String, offset: Option<u64>) -> Result<Vec<UIHistory>, String> { let settings = Settings::new().map_err(|e| e.to_string())?; let db_path = PathBuf::from(settings.db_path.as_str()); let db = HistoryDB::new(db_path, settings.local_timeout).await?; - let history = db.search(query.as_str()).await?; + let history = db.search(offset, query.as_str()).await?; Ok(history) } @@ -62,7 +62,7 @@ async fn global_stats() -> Result<GlobalStats, String> { let mut stats = db.global_stats().await?; - let history = db.list(0, None).await?; + let history = db.list(None, None).await?; let history_stats = stats::compute(&settings, &history, 10, 1); stats.stats = history_stats; diff --git a/ui/src/components/HistorySearch.tsx b/ui/src/components/HistorySearch.tsx index 08bed2a8..b3c8492a 100644 --- a/ui/src/components/HistorySearch.tsx +++ b/ui/src/components/HistorySearch.tsx @@ -3,12 +3,12 @@ import { ArrowPathIcon } from "@heroicons/react/24/outline"; import { MagnifyingGlassIcon } from "@heroicons/react/20/solid"; interface HistorySearchProps { - refresh: (query: string) => void; + query: string; + refresh: () => void; + setQuery: (query: string) => void; } export default function HistorySearch(props: HistorySearchProps) { - let [searchQuery, setSearchQuery] = useState(""); - return ( <div className="flex flex-1 gap-x-4 self-stretch lg:gap-x-6"> <form @@ -35,8 +35,8 @@ export default function HistorySearch(props: HistorySearchProps) { type="search" name="search" onChange={(query) => { - setSearchQuery(query.target.value); - props.refresh(query.target.value); + props.setQuery(query.target.value); + props.refresh(); }} /> </form> @@ -45,7 +45,7 @@ export default function HistorySearch(props: HistorySearchProps) { type="button" className="-m-2.5 p-2.5 text-gray-400 hover:text-gray-500" onClick={() => { - props.refresh(searchQuery); + props.refresh(); }} > <ArrowPathIcon className="h-6 w-6" aria-hidden="true" /> diff --git a/ui/src/pages/History.tsx b/ui/src/pages/History.tsx index d6a18a7c..6eaa6f67 100644 --- a/ui/src/pages/History.tsx +++ b/ui/src/pages/History.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef } from "react"; +import { useEffect, useState, useRef } from "react"; import { useVirtualizer } from "@tanstack/react-virtual"; import HistoryList from "@/components/HistoryList.tsx"; @@ -57,6 +57,8 @@ export default function Search() { const refreshHistory = useStore((state) => state.refreshShellHistory); const historyNextPage = useStore((state) => state.historyNextPage); + let [query, setQuery] = useState(""); + useEffect(() => { (async () => { // nothing rn @@ -81,7 +83,7 @@ export default function Search() { if (lastItem.index < history.length - 1) return; // if we're not at the end yet, bail // we're at the end! more rows plz! - historyNextPage(); + historyNextPage(query); }, [rowVirtualizer.getVirtualItems()]); return ( @@ -94,7 +96,12 @@ export default function Search() { <div className="flex h-16 shrink-0 items-center gap-x-4 border-b border-t border-gray-200 bg-white px-4 shadow-sm sm:gap-x-6 sm:px-6 lg:px-8 history-search"> <HistorySearch - refresh={(query?: string) => { + query={query} + setQuery={(q) => { + setQuery(q); + refreshHistory(q); + }} + refresh={() => { refreshHistory(query); }} /> diff --git a/ui/src/state/store.ts b/ui/src/state/store.ts index 1f1ba13c..fef1b632 100644 --- a/ui/src/state/store.ts +++ b/ui/src/state/store.ts @@ -27,7 +27,7 @@ interface AtuinState { refreshAliases: () => void; refreshVars: () => void; refreshShellHistory: (query?: string) => void; - historyNextPage: () => void; + historyNextPage: (query?: string) => void; } export const useStore = create<AtuinState>()((set, get) => ({ @@ -83,20 +83,18 @@ export const useStore = create<AtuinState>()((set, get) => ({ historyNextPage: (query?: string) => { let history = get().shellHistory; - let minTimestamp = history[history.length - 1].timestamp; - console.log(minTimestamp); + let offset = history.length - 1; if (query) { - invoke("search", { query: query, minTimestamp: minTimestamp }) + invoke("search", { query: query, offset: offset }) .then((res: any) => { - set({ shellHistory: res }); + set({ shellHistory: [...history, ...res] }); }) .catch((e) => { console.log(e); }); } else { - invoke("list", { minTimestamp: minTimestamp }).then((res: any) => { - console.log(res, history); + invoke("list", { offset: offset }).then((res: any) => { set({ shellHistory: [...history, ...res] }); }); } |